Test #2363
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Test | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| inplinuxx8664: | |
| description: | | |
| Build on Linux x86_64 | |
| required: false | |
| type: choice | |
| options: | |
| - 'yes' | |
| - 'no' | |
| default: 'yes' | |
| inplinuxaarch64: | |
| description: | | |
| Build Linux aarch64 | |
| required: false | |
| type: choice | |
| options: | |
| - 'yes' | |
| - 'no' | |
| default: 'yes' | |
| inpmacos: | |
| description: | | |
| Build macOS | |
| required: false | |
| type: choice | |
| options: | |
| - 'yes' | |
| - 'no' | |
| default: 'yes' | |
| inpwindows: | |
| description: | | |
| Build Windows | |
| required: false | |
| type: choice | |
| options: | |
| - 'yes' | |
| - 'no' | |
| default: 'yes' | |
| inpwindowsaarch64: | |
| description: | | |
| Build Windows aarch64 | |
| required: false | |
| type: choice | |
| options: | |
| - 'yes' | |
| - 'no' | |
| default: 'yes' | |
| push: | |
| branches: [ 'dev', 'main' ] | |
| pull_request: | |
| branches: [main, master, dev] | |
| schedule: | |
| - cron: '30 6 * * *' | |
| env: | |
| RUST_BACKTRACE: 1 | |
| jobs: | |
| linux-build-x86_64: | |
| if: ${{ github.event.inputs.inplinuxx8664 == '' || github.event.inputs.inplinuxx8664 == 'yes' }} | |
| runs-on: ubuntu-latest | |
| name: Linux build x86_64 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 10 | |
| - name: Run cargo tests | |
| run: | | |
| cargo fmt --check | |
| cargo clippy --all-targets -- -D warnings | |
| cargo test | |
| cargo test -p xtask | |
| cargo xtask gen-help --check | |
| - name: Build rig | |
| run: | | |
| make linux-in-docker | |
| - name: Upload build as artifact | |
| uses: actions/upload-artifact@v7 | |
| if: success() | |
| with: | |
| name: rig-linux-x86_64 | |
| path: | | |
| rig-*.tar.gz | |
| r-rig_*_amd64.deb | |
| r-rig-*.x86_64.rpm | |
| linux-tests-x86_64-setup: | |
| needs: linux-build-x86_64 | |
| runs-on: ubuntu-latest | |
| name: Linux test setup x86_64 | |
| outputs: | |
| containers: ${{ steps.matrix-setup-x86_64.outputs.containers }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Set up matrix of containers | |
| id: matrix-setup-x86_64 | |
| run: | | |
| containers=$(make print-linux-variants-json) | |
| echo "containers=$containers" >> $GITHUB_OUTPUT | |
| linux-tests-x86_64: | |
| needs: linux-tests-x86_64-setup | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| container: ${{ fromJson(needs.linux-tests-x86_64-setup.outputs.containers) }} | |
| runs-on: ubuntu-latest | |
| name: ${{ matrix.container }} (x86_64) | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Download build from artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rig-linux-x86_64 | |
| path: . | |
| - name: Uncompress rig build | |
| run: | | |
| mkdir build | |
| tar xzf rig-linux-*.tar.gz -C build | |
| find build | |
| - name: Test | |
| run: | | |
| make linux-test-${{ matrix.container }} | |
| if ls tests/results | grep -q fail; then | |
| echo Some tests failed; | |
| exit 1; | |
| fi | |
| env: | |
| REDHAT_ORG: ${{ secrets.REDHAT_ORG }} | |
| REDHAT_ACTIVATION_KEY_RHEL7: ${{ secrets.REDHAT_ACTIVATION_KEY_RHEL7 }} | |
| REDHAT_ACTIVATION_KEY_RHEL8: ${{ secrets.REDHAT_ACTIVATION_KEY_RHEL8 }} | |
| REDHAT_ACTIVATION_KEY_RHEL9: ${{ secrets.REDHAT_ACTIVATION_KEY_RHEL9 }} | |
| REDHAT_ACTIVATION_KEY_RHEL10: ${{ secrets.REDHAT_ACTIVATION_KEY_RHEL10 }} | |
| linux-build-aarch64: | |
| if: ${{ github.event.inputs.inplinuxaarch64 == '' || github.event.inputs.inplinuxaarch64 == 'yes' }} | |
| runs-on: ubuntu-24.04-arm | |
| name: Linux build aaarch | |
| env: | |
| RUST_BACKTRACE: 1 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 10 | |
| - name: Run cargo tests | |
| run: | | |
| cargo test | |
| - name: Build rig | |
| run: | | |
| make linux-in-docker | |
| - name: Upload build as artifact | |
| uses: actions/upload-artifact@v7 | |
| if: success() | |
| with: | |
| name: rig-linux-aarch64 | |
| path: | | |
| rig-*.tar.gz | |
| r-rig_*_arm64.deb | |
| r-rig-*.aarch64.rpm | |
| linux-tests-aarch64-setup: | |
| needs: linux-build-aarch64 | |
| runs-on: ubuntu-latest | |
| name: Linux test setup aarch64 | |
| outputs: | |
| containers: ${{ steps.matrix-setup-aarch64.outputs.containers }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Set up matrix of containers | |
| id: matrix-setup-aarch64 | |
| run: | | |
| containers=$(make print-linux-variants-json) | |
| echo "containers=$containers" >> $GITHUB_OUTPUT | |
| linux-tests-aarch64: | |
| needs: linux-tests-aarch64-setup | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| container: ${{ fromJson(needs.linux-tests-aarch64-setup.outputs.containers) }} | |
| runs-on: ubuntu-24.04-arm | |
| name: ${{ matrix.container }} (aarch64) | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Download build from artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rig-linux-aarch64 | |
| path: . | |
| - name: Uncompress rig build | |
| run: | | |
| mkdir build | |
| tar xzf rig-linux-*.tar.gz -C build | |
| find build | |
| - name: Test | |
| run: | | |
| make linux-test-${{ matrix.container }} | |
| if ls tests/results | grep -q fail; then | |
| echo Some tests failed; | |
| exit 1; | |
| fi | |
| env: | |
| DOCKER_DEFAULT_PLATFORM: "linux/arm64" | |
| REDHAT_ORG: ${{ secrets.REDHAT_ORG }} | |
| REDHAT_ACTIVATION_KEY_RHEL7: ${{ secrets.REDHAT_ACTIVATION_KEY_RHEL7 }} | |
| REDHAT_ACTIVATION_KEY_RHEL8: ${{ secrets.REDHAT_ACTIVATION_KEY_RHEL8 }} | |
| REDHAT_ACTIVATION_KEY_RHEL9: ${{ secrets.REDHAT_ACTIVATION_KEY_RHEL9 }} | |
| REDHAT_ACTIVATION_KEY_RHEL10: ${{ secrets.REDHAT_ACTIVATION_KEY_RHEL10 }} | |
| macos: | |
| if: ${{ github.event.inputs.inpmacos == '' || github.event.inputs.inpmacos == 'yes' }} | |
| runs-on: ${{ matrix.config.os }} | |
| name: ${{ matrix.config.os }} | |
| env: | |
| RUST_BACKTRACE: 1 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| config: | |
| - { os: macos-15-intel } | |
| - { os: macos-latest } | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 10 | |
| - name: Install rust | |
| run: | | |
| curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o rust.sh | |
| sh rust.sh -y | |
| - name: Build rig | |
| run: | | |
| cargo build --release | |
| - name: Run cargo tests | |
| run: | | |
| cargo clippy --all-targets -- -D warnings | |
| cargo test | |
| - name: Upload build as artifact | |
| uses: actions/upload-artifact@v7 | |
| if: success() | |
| with: | |
| name: rig-${{ matrix.config.os }} | |
| path: target/release/rig | |
| - name: Build user-mode tarball | |
| run: make macos-tarball | |
| shell: bash | |
| - name: Upload user-mode tarball as artifact | |
| uses: actions/upload-artifact@v7 | |
| if: success() | |
| with: | |
| name: rig-macos-tarball-${{ matrix.config.os }} | |
| path: 'rig-*-macos.tar.gz' | |
| - name: Install rig | |
| run: | | |
| sudo cp target/release/rig /usr/local/bin/ | |
| - name: Install bats | |
| run: | | |
| brew unlink bats || true | |
| brew install bats-core | |
| - name: Run tests | |
| run: | | |
| bats tests/test-macos.sh | |
| windows: | |
| if: ${{ github.event.inputs.inpwindows == '' || github.event.inputs.inpwindows == 'yes' }} | |
| runs-on: windows-2022 | |
| name: Windows | |
| env: | |
| RUST_BACKTRACE: 1 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 10 | |
| - name: Install rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install make | |
| run: choco install make | |
| - name: Install curl | |
| run: choco install curl | |
| - run: | | |
| make win | |
| shell: bash | |
| - name: Run cargo tests | |
| run: | | |
| cargo clippy --all-targets -- -D warnings | |
| cargo test | |
| shell: bash | |
| - name: Install rig | |
| run: | | |
| Start-Process .\rig-*.exe -ArgumentList "/verysilent /suppressmsgboxes" -Wait -NoNewWindow | |
| - name: Install bats | |
| run: | | |
| npm install -g bats | |
| - name: Run tests | |
| run: | | |
| bats tests/test-windows.sh | |
| shell: bash | |
| - uses: actions/upload-artifact@v7 | |
| if: success() | |
| with: | |
| name: rig-windows | |
| path: 'rig-*.exe' | |
| - uses: actions/upload-artifact@v7 | |
| if: success() | |
| with: | |
| name: rig-windows-zip | |
| path: 'rig-windows-*.zip' | |
| windows-aarch64-test: | |
| if: ${{ github.event.inputs.inpwindows == '' || github.event.inputs.inpwindows == 'yes' }} | |
| needs: windows | |
| runs-on: windows-11-arm | |
| name: Windows test x86_64 build on aarch64 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 10 | |
| - name: Download build from artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rig-windows | |
| path: . | |
| - name: Install rig | |
| run: | | |
| Start-Process .\rig-*.exe -ArgumentList "/verysilent /suppressmsgboxes" -Wait -NoNewWindow | |
| - name: Install bats | |
| run: | | |
| npm install -g bats | |
| - name: Run tests | |
| run: | | |
| bats tests/test-windows.sh | |
| shell: bash | |
| coverage: | |
| runs-on: ubuntu-latest | |
| name: Test coverage | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 10 | |
| - name: Install cargo-llvm-cov | |
| uses: taiki-e/install-action@cargo-llvm-cov | |
| - name: Generate coverage report | |
| run: cargo llvm-cov --lcov --output-path lcov.info | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| files: lcov.info | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| windows-aarch64: | |
| if: ${{ github.event.inputs.inpwindowsaarch64 == '' || github.event.inputs.inpwindowsaarch64 == 'yes' }} | |
| runs-on: windows-11-arm | |
| name: Windows aarch64 | |
| env: | |
| RUST_BACKTRACE: 1 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 10 | |
| - name: Install rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install make | |
| run: choco install make | |
| - name: Install curl | |
| run: choco install curl | |
| - run: | | |
| make win | |
| shell: bash | |
| - name: Run cargo tests | |
| run: | | |
| cargo test | |
| shell: bash | |
| - uses: actions/upload-artifact@v7 | |
| if: success() | |
| with: | |
| name: rig-windows-aarch64 | |
| path: 'rig-*.exe' | |
| - uses: actions/upload-artifact@v7 | |
| if: success() | |
| with: | |
| name: rig-windows-aarch64-zip | |
| path: 'rig-windows-*.zip' | |
| - name: Install rig | |
| run: | | |
| Start-Process .\rig-*.exe -ArgumentList "/verysilent /suppressmsgboxes" -Wait -NoNewWindow | |
| - name: Install bats | |
| run: | | |
| npm install -g bats | |
| - name: Run tests | |
| run: | | |
| bats tests/test-windows.sh | |
| shell: bash | |
| macos-user-mode: | |
| if: ${{ github.event.inputs.inpmacos == '' || github.event.inputs.inpmacos == 'yes' }} | |
| needs: macos | |
| runs-on: ${{ matrix.config.os }} | |
| name: ${{ matrix.config.os }} (user mode) | |
| env: | |
| RUST_BACKTRACE: 1 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| config: | |
| - { os: macos-15-intel } | |
| - { os: macos-latest } | |
| steps: | |
| - name: Download rig tarball from artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rig-macos-tarball-${{ matrix.config.os }} | |
| path: . | |
| - name: Install rig into ~/.local | |
| run: | | |
| mkdir -p "$HOME/.local" | |
| tar xzf rig-*-macos.tar.gz -C "$HOME/.local" | |
| echo "$HOME/.local/bin" >> "$GITHUB_PATH" | |
| - name: Switch rig to user mode | |
| run: | | |
| rig system user-mode | |
| - name: Install R versions (user mode) | |
| run: | | |
| rig add release | |
| rig add oldrel | |
| rig default release | |
| rig ls | |
| - name: Install a package from source (compilation) | |
| run: | | |
| which R | |
| R --version | |
| R -q -e 'R.home()' | |
| R -q -e 'install.packages("filelock", type = "source")' | |
| R -q -e 'library(filelock)' | |
| linux-user-mode-x86_64: | |
| if: ${{ github.event.inputs.inplinuxx8664 == '' || github.event.inputs.inplinuxx8664 == 'yes' }} | |
| needs: linux-build-x86_64 | |
| runs-on: ubuntu-latest | |
| name: Linux user mode (x86_64) | |
| env: | |
| RUST_BACKTRACE: 1 | |
| steps: | |
| - name: Download rig from artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rig-linux-x86_64 | |
| path: . | |
| - name: Install rig into ~/.local | |
| run: | | |
| mkdir -p "$HOME/.local" | |
| tar xzf rig-linux-*.tar.gz -C "$HOME/.local" | |
| echo "$HOME/.local/bin" >> "$GITHUB_PATH" | |
| - name: Switch rig to user mode | |
| run: | | |
| rig system user-mode | |
| - name: Install R versions (user mode) | |
| run: | | |
| rig add release | |
| rig add oldrel | |
| rig default release | |
| rig ls | |
| - name: Install a package from source (compilation) | |
| run: | | |
| which R | |
| R --version | |
| R -q -e 'R.home()' | |
| R -q -e 'install.packages("filelock", type = "source", repos = "https://cloud.r-project.org")' | |
| R -q -e 'library(filelock)' | |
| - name: Render text with the cairo device | |
| run: | | |
| rig system dirs --fonts | |
| ls "$(rig system dirs --fonts)" | |
| Rscript -e 'f <- tempfile(fileext = ".png"); png(f); plot(1); text(1, 1, "hello"); dev.off(); stopifnot(file.info(f)$size > 1000)' | |
| # --vanilla skips Renviron.site, so this checks that FONTCONFIG_FILE | |
| # is set from the base Rprofile. | |
| Rscript --vanilla -e 'f <- tempfile(fileext = ".png"); png(f); plot(1); text(1, 1, "hello"); dev.off(); stopifnot(file.info(f)$size > 1000)' | |
| linux-user-mode-aarch64: | |
| if: ${{ github.event.inputs.inplinuxaarch64 == '' || github.event.inputs.inplinuxaarch64 == 'yes' }} | |
| needs: linux-build-aarch64 | |
| runs-on: ubuntu-24.04-arm | |
| name: Linux user mode (aarch64) | |
| env: | |
| RUST_BACKTRACE: 1 | |
| steps: | |
| - name: Download rig from artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rig-linux-aarch64 | |
| path: . | |
| - name: Install rig into ~/.local | |
| run: | | |
| mkdir -p "$HOME/.local" | |
| tar xzf rig-linux-*.tar.gz -C "$HOME/.local" | |
| echo "$HOME/.local/bin" >> "$GITHUB_PATH" | |
| - name: Switch rig to user mode | |
| run: | | |
| rig system user-mode | |
| - name: Install R versions (user mode) | |
| run: | | |
| rig add release | |
| rig add oldrel | |
| rig default release | |
| rig ls | |
| - name: Install a package from source (compilation) | |
| run: | | |
| which R | |
| R --version | |
| R -q -e 'R.home()' | |
| R -q -e 'install.packages("filelock", type = "source", repos = "https://cloud.r-project.org")' | |
| R -q -e 'library(filelock)' | |
| - name: Render text with the cairo device | |
| run: | | |
| rig system dirs --fonts | |
| ls "$(rig system dirs --fonts)" | |
| Rscript -e 'f <- tempfile(fileext = ".png"); png(f); plot(1); text(1, 1, "hello"); dev.off(); stopifnot(file.info(f)$size > 1000)' | |
| # --vanilla skips Renviron.site, so this checks that FONTCONFIG_FILE | |
| # is set from the base Rprofile. | |
| Rscript --vanilla -e 'f <- tempfile(fileext = ".png"); png(f); plot(1); text(1, 1, "hello"); dev.off(); stopifnot(file.info(f)$size > 1000)' | |
| # The real regression test for the fontconfig setup: a container with no | |
| # fontconfig configuration and no fonts at all, which is where the portable | |
| # R builds used to crash on the first plot. | |
| linux-user-mode-no-fontconfig: | |
| if: ${{ github.event.inputs.inplinuxx8664 == '' || github.event.inputs.inplinuxx8664 == 'yes' }} | |
| needs: linux-build-x86_64 | |
| runs-on: ubuntu-latest | |
| name: Linux user mode, no system fontconfig (x86_64) | |
| container: debian:13-slim | |
| env: | |
| RUST_BACKTRACE: 1 | |
| RIG_MODE: user | |
| steps: | |
| - name: Install the bare minimum | |
| run: | | |
| apt-get update | |
| apt-get install -y --no-install-recommends ca-certificates curl | |
| # Deliberately no `fontconfig` and no font package. | |
| test ! -e /etc/fonts | |
| - name: Download rig from artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rig-linux-x86_64 | |
| path: . | |
| - name: Install rig into ~/.local | |
| run: | | |
| mkdir -p "$HOME/.local" | |
| tar xzf rig-linux-*.tar.gz -C "$HOME/.local" | |
| echo "$HOME/.local/bin" >> "$GITHUB_PATH" | |
| - name: Install R | |
| run: | | |
| rig add release | |
| rig ls | |
| - name: Render text with the cairo device | |
| run: | | |
| ls "$(rig system dirs --fonts)/fonts" | |
| Rscript -e 'f <- tempfile(fileext = ".png"); png(f); plot(1); text(1, 1, "hello"); dev.off(); stopifnot(file.info(f)$size > 1000)' | |
| Rscript --vanilla -e 'f <- tempfile(fileext = ".png"); png(f); plot(1); text(1, 1, "hello"); dev.off(); stopifnot(file.info(f)$size > 1000)' | |
| - name: --without-fonts is idempotent and keeps the existing fonts | |
| run: | | |
| rig add oldrel --without-fonts | |
| # The fonts an earlier install downloaded must still be configured. | |
| grep -q "$(rig system dirs --fonts)/fonts" "$(rig system dirs --fonts)/fonts.conf" | |
| # And exactly one rig block in the base Rprofile, after two installs. | |
| rig add release | |
| test "$(grep -c '## rig FONTCONFIG_FILE start' "$(rig system dirs --r)/current/lib/R/library/base/R/Rprofile")" = 1 | |
| windows-user-mode: | |
| if: ${{ github.event.inputs.inpwindows == '' || github.event.inputs.inpwindows == 'yes' }} | |
| needs: windows | |
| runs-on: windows-2022 | |
| name: Windows (user mode) | |
| env: | |
| RUST_BACKTRACE: 1 | |
| steps: | |
| - name: Download rig zip from artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rig-windows-zip | |
| path: . | |
| - name: Install rig into %USERPROFILE%\.local | |
| run: | | |
| $zip = Get-ChildItem rig-windows-*.zip | Select-Object -First 1 | |
| New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.local" | Out-Null | |
| Expand-Archive -Path $zip.FullName -DestinationPath "$env:USERPROFILE\.local" -Force | |
| Add-Content -Path $env:GITHUB_PATH -Value "$env:USERPROFILE\.local\bin" | |
| - name: Switch rig to user mode | |
| shell: bash | |
| run: | | |
| rig system user-mode | |
| - name: Install R versions (user mode) | |
| shell: bash | |
| run: | | |
| rig add release | |
| rig add oldrel | |
| rig default release | |
| rig add rtools | |
| rig ls | |
| - name: Install a package from source (compilation) | |
| run: | | |
| RS --version | |
| RS -q -e "R.home()" | |
| RS -q -e "install.packages('filelock', type = 'source')" | |
| RS -q -e "library(filelock)" | |
| windows-aarch64-user-mode: | |
| if: ${{ github.event.inputs.inpwindowsaarch64 == '' || github.event.inputs.inpwindowsaarch64 == 'yes' }} | |
| needs: windows-aarch64 | |
| runs-on: windows-11-arm | |
| name: Windows aarch64 (user mode) | |
| env: | |
| RUST_BACKTRACE: 1 | |
| steps: | |
| - name: Download rig zip from artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rig-windows-aarch64-zip | |
| path: . | |
| - name: Install rig into %USERPROFILE%\.local | |
| run: | | |
| $zip = Get-ChildItem rig-windows-*.zip | Select-Object -First 1 | |
| New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.local" | Out-Null | |
| Expand-Archive -Path $zip.FullName -DestinationPath "$env:USERPROFILE\.local" -Force | |
| Add-Content -Path $env:GITHUB_PATH -Value "$env:USERPROFILE\.local\bin" | |
| - name: Switch rig to user mode | |
| shell: bash | |
| run: | | |
| rig system user-mode | |
| - name: Install R versions (user mode) | |
| shell: bash | |
| run: | | |
| rig add release | |
| rig add oldrel | |
| rig default release | |
| rig add rtools | |
| rig ls | |
| - name: Install a package from source (compilation) | |
| run: | | |
| RS --version | |
| RS -q -e "R.home()" | |
| RS -q -e "install.packages('filelock', type = 'source')" | |
| RS -q -e "library(filelock)" |