diff --git a/.github/citools/common/gh-setup-env b/.github/citools/common/gh-setup-env index 5483b53a..d8614004 100755 --- a/.github/citools/common/gh-setup-env +++ b/.github/citools/common/gh-setup-env @@ -18,159 +18,181 @@ main() { print_ruler - source /etc/profile.d/go.sh || track_errors - - printf "Adding Go paths to GITHUB_PATH...\n" - printf "%s\n" "${GOPATH}/bin" | tee -a "${GITHUB_PATH}" || track_errors - printf "\n" - - printf "Adding Go paths to GITHUB_ENV...\n" - printf "%s=%s\n" "GOROOT" "${GOROOT}" | tee -a "${GITHUB_ENV}" || track_errors - printf "%s=%s\n" "GOPATH" "${GOPATH}" | tee -a "${GITHUB_ENV}" || track_errors - printf "%s=%s\n" "GOBIN" "${GOPATH}/bin" | tee -a "${GITHUB_ENV}" || track_errors - printf "%s=%s\n" "GOSRC" "${GOPATH}/src" | tee -a "${GITHUB_ENV}" || track_errors - printf "\n" - - if [ "${HOSTTYPE}" = x86_64 ]; then - printf "%s=%s\n" "GOARCH" "amd64" | tee -a "${GITHUB_ENV}" || track_errors - elif [ "${HOSTTYPE}" = i686 ]; then - printf "%s=%s\n" "GOARCH" "i386" | tee -a "${GITHUB_ENV}" || track_errors - elif [ "${HOSTTYPE}" = aarch64 ]; then - printf "%s=%s\n" "GOARCH" "arm64" | tee -a "${GITHUB_ENV}" || track_errors + if [[ -f /etc/profile.d/go.sh ]]; then + source /etc/profile.d/go.sh || track_errors + + printf "Adding Go paths to GITHUB_PATH...\n" + printf "%s\n" "${GOPATH}/bin" | tee -a "${GITHUB_PATH}" || track_errors + printf "\n" + + printf "Adding Go paths to GITHUB_ENV...\n" + printf "%s=%s\n" "GOROOT" "${GOROOT}" | tee -a "${GITHUB_ENV}" || track_errors + printf "%s=%s\n" "GOPATH" "${GOPATH}" | tee -a "${GITHUB_ENV}" || track_errors + printf "%s=%s\n" "GOBIN" "${GOPATH}/bin" | tee -a "${GITHUB_ENV}" || track_errors + printf "%s=%s\n" "GOSRC" "${GOPATH}/src" | tee -a "${GITHUB_ENV}" || track_errors + printf "\n" + + if [ "${HOSTTYPE}" = x86_64 ]; then + printf "%s=%s\n" "GOARCH" "amd64" | tee -a "${GITHUB_ENV}" || track_errors + elif [ "${HOSTTYPE}" = i686 ]; then + printf "%s=%s\n" "GOARCH" "i386" | tee -a "${GITHUB_ENV}" || track_errors + elif [ "${HOSTTYPE}" = aarch64 ]; then + printf "%s=%s\n" "GOARCH" "arm64" | tee -a "${GITHUB_ENV}" || track_errors + fi + printf "\n" + + printf "Setup Go symlinks for github user:\n" + cd "${HOME}" || track_errors + if [[ ! -d go ]]; then + ln -sv "${GOPATH}" go || track_errors + fi + if [[ ! -d sdk ]]; then + ln -sv "${GO_PREFIX}/go-sdk" sdk || track_errors + fi + ls -l ~/go ~/sdk + cd - || track_errors + printf "\n" + + echo Adding source /etc/profile.d/go.sh to ~/.bashrc + echo '. /etc/profile.d/go.sh' | tee -a "${HOME}/.bashrc" || track_errors + printf "\n" + + print_ruler fi - printf "\n" - printf "Setup Go symlinks for github user:\n" - cd "${HOME}" || track_errors - if [[ ! -d go ]]; then - ln -sv "${GOPATH}" go || track_errors + if [[ -f /etc/profile.d/rust.sh ]]; then + source /etc/profile.d/rust.sh || track_errors + + printf "Adding Rust paths to GITHUB_PATH...\n" + printf "%s\n" "${RUSTBIN}" | tee -a "${GITHUB_PATH}" || track_errors + printf "\n" + + printf "Adding Go paths to GITHUB_ENV...\n" + if [[ -n ${RUSTC_WRAPPER} ]]; then + printf "%s=%s\n" "RUSTC_WRAPPER" "${RUSTC_WRAPPER}" | tee -a "${GITHUB_ENV}" || track_errors + fi + if [[ -n ${CARGO_REGISTRIES_CRATES_IO_PROTOCOL} ]]; then + printf "%s=%s\n" "CARGO_REGISTRIES_CRATES_IO_PROTOCOL" "${CARGO_REGISTRIES_CRATES_IO_PROTOCOL}" | tee -a "${GITHUB_ENV}" || track_errors + fi + printf "\n" + + echo Adding source /etc/profile.d/rust.sh to ~/.bashrc + echo '. /etc/profile.d/rust.sh' | tee -a "${HOME}/.bashrc" || track_errors + printf "\n" + + printf "Setup Rust symlinks for github user:\n" + cd "${HOME}" || track_errors + if [[ ! -d .cargo ]]; then + ln -sv "${CARGO_HOME}" .cargo || track_errors + fi + if [[ ! -d .rustup ]]; then + ln -sv "${RUSTUP_HOME}" .rustup || track_errors + fi + ls -l ~/.cargo ~/.rustup + cd - || track_errors + printf "\n" + + print_ruler fi - if [[ ! -d sdk ]]; then - ln -sv "${GO_PREFIX}/go-sdk" sdk || track_errors - fi - ls -l ~/go ~/sdk - cd - || track_errors - printf "\n" - - echo Adding source /etc/profile.d/go.sh to ~/.bashrc - echo '. /etc/profile.d/go.sh' | tee -a "${HOME}/.bashrc" || track_errors - printf "\n" - - print_ruler - source /etc/profile.d/rust.sh || track_errors + if [[ -f /etc/profile.d/ruby.sh ]]; then + source /etc/profile.d/ruby.sh || track_errors - printf "Adding Rust paths to GITHUB_PATH...\n" - printf "%s\n" "${RUSTBIN}" | tee -a "${GITHUB_PATH}" || track_errors - printf "\n" + printf "Adding Ruby paths to GITHUB_PATH...\n" + printf "%s\n" "/usr/local/rbenv/bin" "/usr/local/rbenv/shims" | tee -a "${GITHUB_PATH}" - printf "Adding Go paths to GITHUB_ENV...\n" - if [[ -n ${RUSTC_WRAPPER} ]]; then - printf "%s=%s\n" "RUSTC_WRAPPER" "${RUSTC_WRAPPER}" | tee -a "${GITHUB_ENV}" || track_errors - fi - if [[ -n ${CARGO_REGISTRIES_CRATES_IO_PROTOCOL} ]]; then - printf "%s=%s\n" "CARGO_REGISTRIES_CRATES_IO_PROTOCOL" "${CARGO_REGISTRIES_CRATES_IO_PROTOCOL}" | tee -a "${GITHUB_ENV}" || track_errors - fi - printf "\n" + echo Adding source /etc/profile.d/ruby.sh to ~/.bashrc + echo '. /etc/profile.d/ruby.sh' | tee -a "${HOME}/.bashrc" || track_errors + printf "\n" - echo Adding source /etc/profile.d/rust.sh to ~/.bashrc - echo '. /etc/profile.d/rust.sh' | tee -a "${HOME}/.bashrc" || track_errors - printf "\n" + printf "Setup Ruby symlinks for github user:\n" + cd "${HOME}" || track_errors + if [[ ! -d .rbenv ]]; then + ln -sv "/usr/local/rbenv" .rbenv || track_errors + fi + ls -l ~/.rbenv + cd - || track_errors + printf "\n" - printf "Setup Rust symlinks for github user:\n" - cd "${HOME}" || track_errors - if [[ ! -d .cargo ]]; then - ln -sv "${CARGO_HOME}" .cargo || track_errors + print_ruler fi - if [[ ! -d .rustup ]]; then - ln -sv "${RUSTUP_HOME}" .rustup || track_errors - fi - ls -l ~/.cargo ~/.rustup - cd - || track_errors - printf "\n" - print_ruler + if [[ -f /etc/profile.d/nodejs.sh ]]; then + source /etc/profile.d/nodejs.sh || track_errors - source /etc/profile.d/ruby.sh || track_errors + printf "Adding NodeJS paths to GITHUB_PATH...\n" + printf "%s\n" "/usr/local/nodenv/bin" "/usr/local/nodenv/shims" | tee -a "${GITHUB_PATH}" - printf "Adding Ruby paths to GITHUB_PATH...\n" - printf "%s\n" "/usr/local/rbenv/bin" "/usr/local/rbenv/shims" | tee -a "${GITHUB_PATH}" + echo Adding source /etc/profile.d/nodejs.sh to ~/.bashrc + echo '. /etc/profile.d/nodejs.sh' | tee -a "${HOME}/.bashrc" || track_errors + printf "\n" - echo Adding source /etc/profile.d/ruby.sh to ~/.bashrc - echo '. /etc/profile.d/ruby.sh' | tee -a "${HOME}/.bashrc" || track_errors - printf "\n" + printf "Setup NodeJS symlinks for github user:\n" + cd "${HOME}" || track_errors + if [[ ! -d .nodenv ]]; then + ln -sv "/usr/local/nodenv" .nodenv || track_errors + fi + ls -l ~/.nodenv + cd - || track_errors + printf "\n" - printf "Setup Ruby symlinks for github user:\n" - cd "${HOME}" || track_errors - if [[ ! -d .rbenv ]]; then - ln -sv "/usr/local/rbenv" .rbenv || track_errors + print_ruler fi - ls -l ~/.rbenv - cd - || track_errors - printf "\n" - print_ruler + if [[ -f /etc/profile.d/python.sh ]]; then + source /etc/profile.d/python.sh || track_errors - source /etc/profile.d/nodejs.sh || track_errors + printf "Adding Python paths to GITHUB_PATH...\n" + printf "%s\n" "/usr/local/pyenv/bin" "/usr/local/pyenv/shims" | tee -a "${GITHUB_PATH}" - printf "Adding NodeJS paths to GITHUB_PATH...\n" - printf "%s\n" "/usr/local/nodenv/bin" "/usr/local/nodenv/shims" | tee -a "${GITHUB_PATH}" + echo Adding source /etc/profile.d/python.sh to ~/.bashrc + echo '. /etc/profile.d/python.sh' | tee -a "${HOME}/.bashrc" || track_errors + printf "\n" - echo Adding source /etc/profile.d/nodejs.sh to ~/.bashrc - echo '. /etc/profile.d/nodejs.sh' | tee -a "${HOME}/.bashrc" || track_errors - printf "\n" + printf "Setup Python symlinks for github user:\n" + cd "${HOME}" || track_errors + if [[ ! -d .pyenv ]]; then + ln -sv "/usr/local/pyenv" .pyenv || track_errors + fi + ls -l ~/.pyenv + cd - || track_errors + printf "\n" - printf "Setup NodeJS symlinks for github user:\n" - cd "${HOME}" || track_errors - if [[ ! -d .nodenv ]]; then - ln -sv "/usr/local/nodenv" .nodenv || track_errors + print_ruler fi - ls -l ~/.nodenv - cd - || track_errors - printf "\n" - print_ruler + if [[ -f /etc/profile.d/gleam.sh ]]; then + source /etc/profile.d/gleam.sh || track_errors - source /etc/profile.d/python.sh || track_errors + printf "Adding Gleam paths to GITHUB_PATH...\n" + printf "%s\n" "/usr/local/erlang/bin" "/usr/local/rebar3/bin" | tee -a "${GITHUB_PATH}" - printf "Adding Python paths to GITHUB_PATH...\n" - printf "%s\n" "/usr/local/pyenv/bin" "/usr/local/pyenv/shims" | tee -a "${GITHUB_PATH}" + echo Adding source /etc/profile.d/gleam.sh to ~/.bashrc + echo '. /etc/profile.d/gleam.sh' | tee -a "${HOME}/.bashrc" || track_errors + printf "\n" - echo Adding source /etc/profile.d/python.sh to ~/.bashrc - echo '. /etc/profile.d/python.sh' | tee -a "${HOME}/.bashrc" || track_errors - printf "\n" + printf "Setup Gleam symlinks for github user:\n" + cd "${HOME}" || track_errors + if [[ ! -d .pyenv ]]; then + mkdir .cache || track_errors + ln -sv "/usr/local/rebar3" .cache/rebar3 || track_errors + fi + ls -l ~/.cache ~/.cache/rebar3 + cd - || track_errors + printf "\n" - printf "Setup Python symlinks for github user:\n" - cd "${HOME}" || track_errors - if [[ ! -d .pyenv ]]; then - ln -sv "/usr/local/pyenv" .pyenv || track_errors + print_ruler fi - ls -l ~/.pyenv - cd - || track_errors - printf "\n" - - print_ruler - source /etc/profile.d/gleam.sh || track_errors + if [[ -f /etc/profile.d/r.sh ]]; then + source /etc/profile.d/r.sh || track_errors - printf "Adding Gleam paths to GITHUB_PATH...\n" - printf "%s\n" "/usr/local/erlang/bin" "/usr/local/rebar3/bin" | tee -a "${GITHUB_PATH}" + echo Adding source /etc/profile.d/r.sh to ~/.bashrc + echo '. /etc/profile.d/r.sh' | tee -a "${HOME}/.bashrc" || track_errors + printf "\n" - echo Adding source /etc/profile.d/gleam.sh to ~/.bashrc - echo '. /etc/profile.d/gleam.sh' | tee -a "${HOME}/.bashrc" || track_errors - printf "\n" - - printf "Setup Gleam symlinks for github user:\n" - cd "${HOME}" || track_errors - if [[ ! -d .pyenv ]]; then - mkdir .cache || track_errors - ln -sv "/usr/local/rebar3" .cache/rebar3 || track_errors + print_ruler fi - ls -l ~/.cache ~/.cache/rebar3 - cd - || track_errors - printf "\n" - - print_ruler tail -n 1000 -v "${GITHUB_PATH}" diff --git a/.github/citools/includes/wrapper-library b/.github/citools/includes/wrapper-library index 925acb77..6159899e 100644 --- a/.github/citools/includes/wrapper-library +++ b/.github/citools/includes/wrapper-library @@ -260,3 +260,33 @@ show_tool_versions_gleam() { # md_code_tag printf "\n" } # show_tool_versions_gleam() + +show_tool_versions_r_short() { + # md_code_tag text + printf "R versions:\n" + printf "\n" + R --version | paste /dev/null - + printf "\n" + Rscript --version | paste /dev/null - + # md_code_tag + printf "\n" +} # show_tool_versions_r_short() + +show_tool_versions_r() { + show_tool_versions_r_short + + if [[ -z ${GITHUB_ACTIONS} ]]; then + return + fi + + # md_code_tag text + printf "Installed R packages:\n" + printf "\n" + printf "null\n" + R --no-save <<-EOF + p <- available.packages() + p + EOF + # md_code_tag + printf "\n" +} # show_tool_versions_r() diff --git a/.github/citools/python/python-setup-install b/.github/citools/python/python-setup-install index 4b3efacd..c55a25bb 100755 --- a/.github/citools/python/python-setup-install +++ b/.github/citools/python/python-setup-install @@ -48,11 +48,21 @@ main() { zlib1g-dev ) + echo Running: sudo apt update + time sudo apt update || track_errors + + print_ruler + echo Running: sudo apt install -y "${debs[@]}" time sudo apt install -y "${debs[@]}" || track_errors print_ruler + echo Running: sudo apt-mark manual "${debs[@]}" + time sudo apt-mark manual "${debs[@]}" || track_errors + + print_ruler + echo Running: export PYTHON_CONFIGURE_OPTS="--enable-shared" export PYTHON_CONFIGURE_OPTS="--enable-shared" diff --git a/.github/citools/r/r-lint-formatter b/.github/citools/r/r-lint-formatter new file mode 100755 index 00000000..0541d363 --- /dev/null +++ b/.github/citools/r/r-lint-formatter @@ -0,0 +1,26 @@ +#!/bin/bash +# +# .github/citools/r/r-lint-formatter +# + +# shellcheck disable=SC1091 +source ../../.github/citools/includes/wrapper-library || exit + +declare -i retval=0 + +main() { + printf "\nRunning R Formatter\n\n" + + show_tool_versions_r_short + + print_ruler + + run_command rfmt + + print_ruler + + echo Exit code: "${retval}" + return "${retval}" +} + +time main "${@}" diff --git a/.github/citools/r/r-setup-config b/.github/citools/r/r-setup-config new file mode 100755 index 00000000..46ae7996 --- /dev/null +++ b/.github/citools/r/r-setup-config @@ -0,0 +1,24 @@ +#!/bin/bash +# +# .github/citools/r/r-setup-config +# + +# shellcheck disable=SC1091 +source ../../.github/citools/includes/wrapper-library || exit + +declare -i retval=0 + +main() { + printf "Setup R Environment\n\n" + + print_ruler + + ../../.github/citools/common/gh-setup-env || track_errors + + print_ruler + + echo Exit code: "${retval}" + return "${retval}" +} + +time main "${@}" diff --git a/.github/citools/r/r-setup-install b/.github/citools/r/r-setup-install new file mode 100755 index 00000000..1fc807d6 --- /dev/null +++ b/.github/citools/r/r-setup-install @@ -0,0 +1,148 @@ +#!/bin/bash +# +# .github/citools/r/r-setup-install +# + +# shellcheck disable=SC1091 +source ../../.github/citools/includes/wrapper-library || exit + +declare -i retval=0 + +main() { + printf "R Installation\n\n" + + print_ruler + + echo Running: gpg --keyserver keyserver.ubuntu.com --recv-key '95C0FAF38DB3CCAD0C080A7BDC78B2DDEABC47B7' + gpg --keyserver keyserver.ubuntu.com --recv-key '95C0FAF38DB3CCAD0C080A7BDC78B2DDEABC47B7' + printf "\n" + + echo Running: gpg --armor --export '95C0FAF38DB3CCAD0C080A7BDC78B2DDEABC47B7' | sudo tee /etc/apt/trusted.gpg.d/cran_debian_key.asc + gpg --armor --export '95C0FAF38DB3CCAD0C080A7BDC78B2DDEABC47B7' | sudo tee /etc/apt/trusted.gpg.d/cran_debian_key.asc + printf "\n" + + echo Adding: deb http://cloud.r-project.org/bin/linux/debian bookworm-cran40/ to /etc/apt/sources.list.d/cran.list + printf "%s\n" "deb http://cloud.r-project.org/bin/linux/debian bookworm-cran40/" | sudo tee -a /etc/apt/sources.list.d/cran.list + + print_ruler + + echo Running: sudo apt update + time sudo apt update || track_errors + + print_ruler + + local -a debs + debs=( + r-base + r-base-dev + r-base-core + r-recommended + gdebi-core + ) + + echo Running: sudo apt install -y "${debs[@]}" + time sudo apt install -y "${debs[@]}" || track_errors + + print_ruler + + echo Running: sudo apt-mark manual "${debs[@]}" + time sudo apt-mark manual "${debs[@]}" || track_errors + + print_ruler + + if ! grep -q R_LIBS_USER /etc/profile.d/r.sh; then + sudo tee /etc/profile.d/r.sh <<-EOF + export R_LIBS_USER="/usr/local/lib/R/site-library/" + EOF + + mkdir -pv /usr/local/lib/R/site-library + chmod -v 0775 /usr/local/lib/R/site-library + chgrp -v -R adm /usr/local/lib/R/site-library + setfacl -RPdm g:adm:w /usr/local/lib/R/site-library + fi + + source /etc/profile.d/python.sh + source /etc/profile.d/r.sh + + print_ruler + + echo Running: pyenv install anaconda3 + time pyenv install anaconda3 || track_errors + printf "\n" + + echo Creating: /usr/local/lib/R/.python-version + printf "%s\n" "anaconda3" | tee /usr/local/lib/R/.python-version + printf "\n" + + print_ruler + + tee /tmp/r-setup.rscript <<-EOF + setwd(system("pwd", intern = T) ) + + system("pyenv version", intern = T) + system("pyenv global anaconda3", intern = T) + system("pyenv version", intern = T) + + install.packages("this.path") + install.packages("testthat") + + install.packages("styler") + install.packages("lintr") + install.packages("languageserver") + # install.packages("nvimcom") + + install.packages("tidyverse") + library(tidyverse) + + system("pyenv version", intern = T) + system("bash -c 'pyenv global $(pyenv versions --bare | grep -E '^3[.]' | tail -n 1)'", intern = T) + system("pyenv version", intern = T) + EOF + + echo Running: Rscript /tmp/r-setup.rscript + time Rscript /tmp/r-setup.rscript || track_errors + printf "\n" + + print_ruler + + echo Running: wget -c https://download2.rstudio.org/server/jammy/amd64/rstudio-server-2023.12.1-402-amd64.deb + time wget -c https://download2.rstudio.org/server/jammy/amd64/rstudio-server-2023.12.1-402-amd64.deb + printf "\n" + + echo Running: sudo gdebi --non-interactive ./rstudio-server-2023.12.1-402-amd64.deb + time sudo gdebi --non-interactive ./rstudio-server-2023.12.1-402-amd64.deb + printf "\n" + + echo Running: sudo apt-mark manual rstudio-server + time sudo apt-mark manual rstudio-server + printf "\n" + + echo Running: rm -fv ./rstudio-server-2023.12.1-402-amd64.deb + rm -fv ./rstudio-server-2023.12.1-402-amd64.deb + + print_ruler + + echo Running: pyenv global "$(pyenv versions --bare | grep -E '^3[.]' | tail -n 1)" + pyenv global "$(pyenv versions --bare | grep -E '^3[.]' | tail -n 1)" || track_errors + + print_ruler + + echo Running: du -shc /usr/local/pyenv/versions/anaconda3-*/pkgs + du -shc /usr/local/pyenv/versions/anaconda3-*/pkgs + + print_ruler + + echo Running: rm -rf /usr/local/pyenv/versions/anaconda3-*"/pkgs/*" + time rm -rf /usr/local/pyenv/versions/anaconda3-*/pkgs/* + + print_ruler + + show_tool_versions_r_short + + print_ruler + + echo Exit code: "${retval}" + return "${retval}" +} + +time main "${@}" diff --git a/.github/citools/r/r-setup-verify b/.github/citools/r/r-setup-verify new file mode 100755 index 00000000..938f9a15 --- /dev/null +++ b/.github/citools/r/r-setup-verify @@ -0,0 +1,54 @@ +#!/bin/bash +# +# .github/citools/r/r-setup-verify +# + +# shellcheck disable=SC1091 +source ../../.github/citools/includes/wrapper-library || exit + +declare -i retval=0 + +declare -A r_cmds + +r_cmds=( + [R]=$( + command -v R >&/dev/null + echo "$?" + ) + [Rscript]=$( + command -v Rscript >&/dev/null + echo "$?" + ) +) + +main() { + printf "Verifying R Installation\n\n" + + print_ruler + + printf "PATH=%s\n" "${PATH}" + + print_ruler + + for key in "${!r_cmds[@]}"; do + if [[ ${r_cmds[${key}]} -ne 0 ]]; then + printf "ERROR: command [%s] not found.\n" "${key}" + ((retval++)) + fi + done + + if [[ ${retval} -ne 0 ]]; then + return "${retval}" + fi + + print_ruler + + show_tool_versions_r + + print_ruler + + echo Exit code: "${retval}" + return "${retval}" +} + +time main "${@}" diff --git a/.github/citools/r/r-test b/.github/citools/r/r-test new file mode 100755 index 00000000..637064ff --- /dev/null +++ b/.github/citools/r/r-test @@ -0,0 +1,33 @@ +#!/bin/bash +# +# .github/citools/r/r-test +# + +# shellcheck disable=SC1091 +source ../../.github/citools/includes/wrapper-library || exit + +declare -i retval=0 + +main() { + printf "\nRunning R Tests\n\n" + + show_tool_versions_r_short + + print_ruler + + local -a test_files + local test_file + + mapfile -t test_files < <(jq -r '.files.test[]' .exercism/config.json) + + for test_file in "${test_files[@]}"; do + run_command Rscript "${test_file}" || ((retval++)) + done + + print_ruler + + echo Exit code: "${retval}" + return "${retval}" +} + +time main "${@}" diff --git a/.github/citools/ruby/ruby-setup-install b/.github/citools/ruby/ruby-setup-install index 55387c52..34dfd37d 100755 --- a/.github/citools/ruby/ruby-setup-install +++ b/.github/citools/ruby/ruby-setup-install @@ -51,6 +51,11 @@ main() { print_ruler + echo Running: sudo apt-mark manual "${debs[@]}" + time sudo apt-mark manual "${debs[@]}" || track_errors + + print_ruler + echo Running: curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer \| bash time curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash || track_errors diff --git a/.github/citools/wasm/wasm-setup-install b/.github/citools/wasm/wasm-setup-install index 27e66db2..0d28e166 100755 --- a/.github/citools/wasm/wasm-setup-install +++ b/.github/citools/wasm/wasm-setup-install @@ -30,6 +30,11 @@ main() { print_ruler + echo Running: sudo apt-mark manual "${debs[@]}" + time sudo apt-mark manual "${debs[@]}" || track_errors + + print_ruler + show_tool_versions_node_short print_ruler diff --git a/.github/docker/include b/.github/docker/include index dcc419e7..e7a3f29d 100644 --- a/.github/docker/include +++ b/.github/docker/include @@ -7,6 +7,8 @@ # Notes: # - use sh/posix syntax only +export IMAGE_NAME="${1:-}" + layer_begin() { printf "=== %s:%s start ===\n\n" "${0}" "layer_begin()" @@ -36,20 +38,6 @@ layer_begin() { layer_end() { printf "=== %s:%s start ===\n\n" "${0}" "layer_end()" - echo Running: apt-get purge -y libx11.* libqt.* - apt-get purge -y libx11.* libqt.* || exit - printf "\n" - - echo Running: apt-get remove -y x11-common - apt-get remove -y x11-common || exit - printf "\n" - - for p in $(apt list --installed 2>/dev/null | cut -f1 -d/ | grep -E '^x11-.*$'); do - echo Running: apt remove -y "${p}" - apt remove -y "${p}" || true - printf "\n" - done - echo Running: apt autoremove -y apt autoremove -y || exit printf "\n" @@ -70,5 +58,13 @@ layer_end() { rm -rf /var/lib/apt/lists/* || exit printf "\n" + echo Running: df -h + df -h + printf "\n" + + echo Running: du -shc /* \| grep '[0-9][MGT]' + du -shc /* | grep '[0-9][MGT]' + printf "\n" + printf "=== %s:%s end ===\n\n" "${0}" "layer_end()" } diff --git a/.github/docker/layer-00.00-base-dependencies.sh b/.github/docker/layer-00.00-base-dependencies.sh index e3f2b839..bfe4f97d 100755 --- a/.github/docker/layer-00.00-base-dependencies.sh +++ b/.github/docker/layer-00.00-base-dependencies.sh @@ -17,24 +17,16 @@ main() { apt list --installed >"${HOME}"/apt-pkgs-start.txt printf "\n" - echo Running: apt remove -y "$(apt list --installed | grep -e xorg -e xserver -e qt | cut -f1 -d/)" - # shellcheck disable=SC2046 - apt remove -y $(apt list --installed | grep -e xorg -e xserver -e qt | cut -f1 -d/) || exit - printf "\n" - - echo Running: apt-get purge -y libx11.* libqt.* - apt-get purge -y libx11.* libqt.* || exit - printf "\n" - - echo Running: apt-get remove -y x11-common - apt-get remove -y x11-common || exit - printf "\n" - echo apt install -y "${PACKAGES}" # shellcheck disable=SC2086 apt install -y ${PACKAGES} || exit printf "\n" + echo apt-mark manual "${PACKAGES}" + # shellcheck disable=SC2086 + apt-mark manual ${PACKAGES} || exit + printf "\n" + layer_end "${0}" "$@" } diff --git a/.github/docker/layer-00.05-additional_deps.sh b/.github/docker/layer-00.05-additional_deps.sh new file mode 100755 index 00000000..ef77a237 --- /dev/null +++ b/.github/docker/layer-00.05-additional_deps.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# +# .github/docker/layer-00.05-additional_deps.sh +# + +set -o pipefail + +# this path from inside the container +# shellcheck disable=SC1091 +. /.github/docker/include + +# shellcheck disable=SC1091 +source /.github/citools/includes/wrapper-library || exit + +main() { + declare -i retval=0 + + layer_begin "${0}" "$@" + + echo Running: sudo apt update + time sudo apt update || track_errors + printf "\n" + + local PACKAGES + PACKAGES=( + libcurl4 + libcurl4-doc + libcurl4-openssl-dev + libcurlpp-dev + libcurlpp0 + libfontconfig1-dev + libfreetype6-dev + libfribidi-dev + libharfbuzz-dev + libjpeg-dev + libpng-dev + libtiff5-dev + ) + + echo Running: sudo apt install -y "${PACKAGES[@]}" + time sudo apt install -y "${PACKAGES[@]}" || track_errors + printf "\n" + + echo Running: sudo apt-mark manual "${PACKAGES[@]}" + time sudo apt-mark manual "${PACKAGES[@]}" || track_errors + printf "\n" + + layer_end "${0}" "$@" + + echo Running: return "${retval}" + return "${retval}" +} + +main "${@}" |& tee "${HOME}"/layer-00.05-additional_deps.log diff --git a/.github/docker/layer-00.10-base-daggerio.sh b/.github/docker/layer-00.10-base-daggerio.sh index 015192ea..f6f1969c 100755 --- a/.github/docker/layer-00.10-base-daggerio.sh +++ b/.github/docker/layer-00.10-base-daggerio.sh @@ -9,11 +9,14 @@ set -o pipefail # shellcheck disable=SC1091 . /.github/docker/include +# shellcheck disable=SC1091 +source /.github/citools/includes/wrapper-library || exit + main() { layer_begin "${0}" "$@" echo curl -sSfL https://releases.dagger.io/dagger/install.sh \| sh - curl -sSfL https://releases.dagger.io/dagger/install.sh | sh || exit + curl -sSfL https://releases.dagger.io/dagger/install.sh | sh || track_errors printf "\n" layer_end "${0}" "$@" diff --git a/.github/docker/layer-00.50-base-docker.sh b/.github/docker/layer-00.50-base-docker.sh index 06553640..89319b09 100755 --- a/.github/docker/layer-00.50-base-docker.sh +++ b/.github/docker/layer-00.50-base-docker.sh @@ -9,6 +9,9 @@ set -o pipefail # shellcheck disable=SC1091 . /.github/docker/include +# shellcheck disable=SC1091 +source /.github/citools/includes/wrapper-library || exit + main() { declare -i retval=0 @@ -30,16 +33,20 @@ main() { docker-compose-plugin ) - echo Running: apt update - time apt update || track_errors + echo Running: sudo apt update + time sudo apt update || track_errors + printf "\n" + + echo Running: sudo apt install -y "${DEPS[@]}" + time sudo apt install -y "${DEPS[@]}" || track_errors printf "\n" - echo Running: apt install -y "${DEPS[@]}" - time apt install -y "${DEPS[@]}" || track_errors + echo Running: sudo apt-mark manual "${DEPS[@]}" + time sudo apt-mark manual "${DEPS[@]}" || track_errors printf "\n" - echo Running: install -m 0755 -d /etc/apt/keyrings - install -m 0755 -d /etc/apt/keyrings || track_errors + echo Running: sudo install -m 0755 -d /etc/apt/keyrings + sudo install -m 0755 -d /etc/apt/keyrings || track_errors printf "\n" echo Running: curl -fsSL https://download.docker.com/linux/debian/gpg \| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg @@ -51,12 +58,16 @@ main() { EOF printf "\n" - echo Running: apt update - time apt update || track_errors + echo Running: sudo apt update + time sudo apt update || track_errors + printf "\n" + + echo Running: sudo apt install -y "${PACKAGES[@]}" + time sudo apt install -y "${PACKAGES[@]}" || track_errors printf "\n" - echo Running: apt install -y "${PACKAGES[@]}" - time apt install -y "${PACKAGES[@]}" || track_errors + echo Running: sudo apt-mark manual "${PACKAGES[@]}" + time sudo apt-mark manual "${PACKAGES[@]}" || track_errors printf "\n" layer_end "${0}" "$@" diff --git a/.github/docker/layer-02.00-git.sh b/.github/docker/layer-02.00-git.sh index 71227de5..0dab7d3a 100755 --- a/.github/docker/layer-02.00-git.sh +++ b/.github/docker/layer-02.00-git.sh @@ -27,12 +27,16 @@ main() { gitlint ) - echo Running: apt update - time apt update || track_errors + echo Running: sudo apt update + time sudo apt update || track_errors printf "\n" - echo Running: apt install -y "${PACKAGES[@]}" - time apt install -y "${PACKAGES[@]}" || track_errors + echo Running: sudo apt install -y "${PACKAGES[@]}" + time sudo apt install -y "${PACKAGES[@]}" || track_errors + printf "\n" + + echo Running: sudo apt-mark manual "${PACKAGES[@]}" + time sudo apt-mark manual "${PACKAGES[@]}" || track_errors printf "\n" layer_end "${0}" "$@" diff --git a/.github/docker/layer-09.00-exercism-nodejs.sh b/.github/docker/layer-09.00-exercism-nodejs.sh index 40b881ca..8996c602 100755 --- a/.github/docker/layer-09.00-exercism-nodejs.sh +++ b/.github/docker/layer-09.00-exercism-nodejs.sh @@ -41,8 +41,12 @@ main() { time apt update || track_errors printf "\n" - echo Running: apt install -y "${PACKAGES[@]}" - time apt install -y "${PACKAGES[@]}" || track_errors + echo Running: sudo apt install -y "${PACKAGES[@]}" + time sudo apt install -y "${PACKAGES[@]}" || track_errors + printf "\n" + + echo Running: sudo apt-mark manual "${PACKAGES[@]}" + time sudo apt-mark manual "${PACKAGES[@]}" || track_errors printf "\n" echo Running: curl -fsSL https://github.com/nodenv/nodenv-installer/raw/HEAD/bin/nodenv-installer \| bash diff --git a/.github/docker/layer-10.00-exercism-gcc_clang_llvm.sh b/.github/docker/layer-10.00-exercism-gcc_clang_llvm.sh index a7005213..3a733a97 100755 --- a/.github/docker/layer-10.00-exercism-gcc_clang_llvm.sh +++ b/.github/docker/layer-10.00-exercism-gcc_clang_llvm.sh @@ -75,12 +75,16 @@ main() { time curl -sS https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc || track_errors printf "\n" - echo Running: apt update - time apt update || track_errors + echo Running: sudo apt update + time sudo apt update || track_errors printf "\n" - echo Running: apt install -y "${PACKAGES[@]}" - time apt install -y "${PACKAGES[@]}" || track_errors + echo Running: sudo apt install -y "${PACKAGES[@]}" + time sudo apt install -y "${PACKAGES[@]}" || track_errors + printf "\n" + + echo Running: sudo apt-mark manual "${PACKAGES[@]}" + time sudo apt-mark manual "${PACKAGES[@]}" || track_errors printf "\n" layer_end "${0}" "$@" diff --git a/.github/docker/layer-14.00-exercism-tools.sh b/.github/docker/layer-14.00-exercism-tools.sh index f8df8eb8..c98e1a48 100755 --- a/.github/docker/layer-14.00-exercism-tools.sh +++ b/.github/docker/layer-14.00-exercism-tools.sh @@ -29,8 +29,16 @@ main() { yamllint ) - echo Running: apt install -y "${PACKAGES[@]}" - time apt install -y "${PACKAGES[@]}" || track_errors + echo Running: sudo apt update + time sudo apt update || track_errors + printf "\n" + + echo Running: sudo apt install -y "${PACKAGES[@]}" + time sudo apt install -y "${PACKAGES[@]}" || track_errors + printf "\n" + + echo Running: sudo apt-mark manual "${PACKAGES[@]}" + time sudo apt-mark manual "${PACKAGES[@]}" || track_errors printf "\n" layer_end "${0}" "$@" diff --git a/.github/docker/layer-15.00-exercism-rust.sh b/.github/docker/layer-15.00-exercism-rust.sh index 1de72fd8..0182e0b7 100755 --- a/.github/docker/layer-15.00-exercism-rust.sh +++ b/.github/docker/layer-15.00-exercism-rust.sh @@ -66,8 +66,16 @@ main() { rustfmt ) - echo Running: apt install -y "${PACKAGES[@]}" - time apt install -y "${PACKAGES[@]}" || track_errors + echo Running: sudo apt update + time sudo apt update || track_errors + printf "\n" + + echo Running: sudo apt install -y "${PACKAGES[@]}" + time sudo apt install -y "${PACKAGES[@]}" || track_errors + printf "\n" + + echo Running: sudo apt-mark manual "${PACKAGES[@]}" + time sudo apt-mark manual "${PACKAGES[@]}" || track_errors printf "\n" tee /etc/profile.d/rust.sh <<-EOF diff --git a/.github/docker/layer-16.00-exercism-go.sh b/.github/docker/layer-16.00-exercism-go.sh index dae0f483..50773f13 100755 --- a/.github/docker/layer-16.00-exercism-go.sh +++ b/.github/docker/layer-16.00-exercism-go.sh @@ -206,8 +206,16 @@ main() { toolstash ) - echo Running: apt install -y "${PACKAGES[@]}" - time apt install -y "${PACKAGES[@]}" || track_errors + echo Running: sudo apt update + time sudo apt update || track_errors + printf "\n" + + echo Running: sudo apt install -y "${PACKAGES[@]}" + time sudo apt install -y "${PACKAGES[@]}" || track_errors + printf "\n" + + echo Running: sudo apt-mark manual "${PACKAGES[@]}" + time sudo apt-mark manual "${PACKAGES[@]}" || track_errors printf "\n" # Note to self: make sure that variables in the here-doc are escaped as needed! diff --git a/.github/docker/layer-19.00-exercism-gleam.sh b/.github/docker/layer-19.00-exercism-gleam.sh index 1951bd90..23a7a268 100755 --- a/.github/docker/layer-19.00-exercism-gleam.sh +++ b/.github/docker/layer-19.00-exercism-gleam.sh @@ -57,8 +57,8 @@ main() { time setfacl -RPdm g:adm:w "${ERLANG_ROOT}" "${REBAR3_ROOT}" || track_errors printf "\n" - echo Running: rm -rf "${HOME}/git_remote/*" - time rm -rf "${HOME}/git_remote/*" + echo Running: rm -rf "${HOME}/git_remote/"* + time rm -rf "${HOME}/git_remote/"* printf "\n" layer_end "${0}" "$@" diff --git a/.github/docker/layer-20.00-exercism-r.sh b/.github/docker/layer-20.00-exercism-r.sh new file mode 100755 index 00000000..f546ea60 --- /dev/null +++ b/.github/docker/layer-20.00-exercism-r.sh @@ -0,0 +1,75 @@ +#!/bin/bash +# +# .github/docker/layer-19.00-exercism-r.sh +# + +set -o pipefail + +# this path from for the container +# shellcheck disable=SC1091 +. /.github/docker/include + +# shellcheck disable=SC1091 +source /.github/citools/includes/wrapper-library || exit + +main() { + declare -i retval=0 + + layer_begin "${0}" "$@" + + echo Running: source /etc/profile.d/python.sh + # shellcheck disable=SC1091 + source /etc/profile.d/python.sh || track_errors + printf "\n" + + echo Running: /.github/citools/r/r-setup-install + time /.github/citools/r/r-setup-install || track_errors + printf "\n" + + echo Running: /.github/citools/r/r-setup-config + time /.github/citools/r/r-setup-config || track_errors + printf "\n" + + echo Running: pyenv global anaconda3 + pyenv global anaconda3 + printf "\n" + + # this image only needs the anaconda3 installations + if [[ ${IMAGE_NAME:-} =~ ^ci-anaconda-.*$ ]]; then + cd "${PYENV_ROOT}"/versions/ || track_errors + for pv in ./3*; do + echo Running: pyenv uninstall "${pv}" + time pyenv uninstall "${pv}" + printf "\n" + done + cd - || track_errors + + echo Running: pyenv versions + pyenv versions + printf "\n" + fi + + echo Adding source /etc/profile.d/r.sh to ~/.bashrc and /etc/skel/.bashrc + echo '. /etc/profile.d/r.sh' | tee -a "${HOME}/.bashrc" | tee -a "${HOME}/.profile" | tee -a /etc/skel/.bashrc || track_errors + printf "\n" + + echo Running: source /etc/profile.d/r.sh + # shellcheck disable=SC1091 + source /etc/profile.d/r.sh || track_errors + printf "\n" + + echo Running: chgrp -R adm /usr/local/lib/R/site-library + time chgrp -R adm /usr/local/lib/R/site-library || track_errors + printf "\n" + + echo Running: setfacl -RPdm g:adm:w /usr/local/lib/R/site-library + time setfacl -RPdm g:adm:w /usr/local/lib/R/site-library || track_errors + printf "\n" + + layer_end "${0}" "$@" + + echo Running: return "${retval}" + return "${retval}" +} + +time main "${@}" |& tee "${HOME}"/layer-19.00-exercism-r.log diff --git a/.github/docker/layer-35.00-tools-tailscale.sh b/.github/docker/layer-35.00-tools-tailscale.sh index ffd10a75..4916c792 100755 --- a/.github/docker/layer-35.00-tools-tailscale.sh +++ b/.github/docker/layer-35.00-tools-tailscale.sh @@ -38,17 +38,23 @@ main() { time apt install -y "${PACKAGES[@]}" || track_errors printf "\n" - declare -a GO_PKGS - GO_PKGS=( - golang.zx2c4.com/wireguard@latest - ) + if command -v go >&/dev/null; then + declare -a GO_PKGS + GO_PKGS=( + golang.zx2c4.com/wireguard@latest + ) - declare url - for url in "${GO_PKGS[@]}"; do - echo Running: go install "${url}" - go install "${url}" || track_errors + declare url + for url in "${GO_PKGS[@]}"; do + echo Running: go install "${url}" + go install "${url}" || track_errors + printf "\n" + done + else + printf "\n" + printf "Go not found, skipping installation of extra packages.\n" printf "\n" - done + fi layer_end "${0}" "$@" diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 09064d35..30ec934c 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -20,9 +20,6 @@ on: # yamllint disable-line rule:truthy workflow_dispatch: pull_request: -env: - IMAGE_NAME: ci-generic-debian - defaults: run: shell: bash @@ -98,58 +95,103 @@ jobs: # Set the output named "docs_changed" printf "%s=%s\n" "docs_changed" "${HAS_DIFF}" >> "${GITHUB_OUTPUT}" - stage2: - name: Docker Build + stage2a: + name: Docker Build Base Image strategy: matrix: os: ["ubuntu-latest"] + image: + - ci-base-debian runs-on: "${{ matrix.os }}" needs: [stage1] if: needs.stage1.outputs.docs_changed == 'True' outputs: tag_date: ${{ steps.setup_image_info.outputs.tag_date }} steps: - - name: Setup Env [${{ matrix.os }}] + - name: Setup Env [${{ matrix.os }} - ${{ matrix.image }}] + id: setup_image_info + run: |- + tag_date="$(date +%Y%m%d)" + printf "%s=%s\n" "tag_date" "${tag_date}" >> "${GITHUB_OUTPUT}" + - name: Docker Build Checkout [${{ matrix.os }} - ${{ matrix.image }}] + uses: actions/checkout@v3 + - name: Login to Docker Hub [${{ matrix.os }} - ${{ matrix.image }}] + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Set up Docker Buildx [${{ matrix.os }} - ${{ matrix.image }}] + uses: docker/setup-buildx-action@v2 + - name: Build and push [${{ matrix.os }} - ${{ matrix.image }}] + uses: docker/build-push-action@v4 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{ matrix.image }}:latest,${{ secrets.DOCKERHUB_USERNAME }}/${{ matrix.image }}:${{ steps.setup_image_info.outputs.tag_date }} + target: ${{ matrix.image }} + cache-to: type=gha + stage2b: + name: Docker Build CI Images + strategy: + matrix: + os: ["ubuntu-latest"] + image: + - ci-generic-debian + - ci-anaconda-debian + runs-on: "${{ matrix.os }}" + needs: [stage1, stage2a] + if: needs.stage1.outputs.docs_changed == 'True' + outputs: + tag_date: ${{ steps.setup_image_info.outputs.tag_date }} + steps: + - name: Setup Env [${{ matrix.os }} - ${{ matrix.image }}] id: setup_image_info run: |- tag_date="$(date +%Y%m%d)" printf "%s=%s\n" "tag_date" "${tag_date}" >> "${GITHUB_OUTPUT}" - - name: Docker Build Checkout [${{ matrix.os }}] + - name: Docker Build Checkout [${{ matrix.os }} - ${{ matrix.image }}] uses: actions/checkout@v3 - - name: Login to Docker Hub [${{ matrix.os }}] + - name: Login to Docker Hub [${{ matrix.os }} - ${{ matrix.image }}] uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Set up Docker Buildx [${{ matrix.os }}] + - name: Set up Docker Buildx [${{ matrix.os }} - ${{ matrix.image }}] uses: docker/setup-buildx-action@v2 - - name: Build and push [${{ matrix.os }}] + - name: Build and push [${{ matrix.os }} - ${{ matrix.image }}] uses: docker/build-push-action@v4 with: context: . file: ./Dockerfile push: true - tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest,${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.setup_image_info.outputs.tag_date }} + tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{ matrix.image }}:latest,${{ secrets.DOCKERHUB_USERNAME }}/${{ matrix.image }}:${{ steps.setup_image_info.outputs.tag_date }} + target: ${{ matrix.image }} + cache-from: type=gha stage3: name: Docker Build Check env: ORG: ${{ secrets.DOCKERHUB_USERNAME }} - IMAGE_NAME: ci-generic-debian strategy: matrix: os: - vpayno/ci-generic-debian:latest - - vpayno/ci-generic-debian:${{ needs.stage2.outputs.tag_date }} + - vpayno/ci-generic-debian:${{ needs.stage2b.outputs.tag_date }} + - vpayno/ci-anaconda-debian:latest + - vpayno/ci-anaconda-debian:${{ needs.stage2b.outputs.tag_date }} runs-on: ubuntu-latest container: ${{ matrix.os }} - needs: [stage2] + needs: [stage2b] steps: - name: Test New Container [${{ matrix.os }}] run: |- printf "%s\n" "Hello World!" - name: Docker Build Summary [${{ matrix.os }}] run: |- - ORG_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}" + IMAGE_NAME="${{ matrix.os }}" + IMAGE_NAME="${IMAGE_NAME##*/}" + IMAGE_NAME="${IMAGE_NAME%%:*}" + ORG_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/${IMAGE_NAME}" TOKEN="$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${ORG_IMAGE}:pull" | jq -r .access_token)" { printf "Docker Hub Image Info\n" diff --git a/.github/workflows/docker-test.yml b/.github/workflows/docker-test.yml index c38818c8..23a60d0e 100644 --- a/.github/workflows/docker-test.yml +++ b/.github/workflows/docker-test.yml @@ -22,61 +22,109 @@ defaults: shell: bash jobs: - stage1: - name: Docker Container Test + stage1a: + name: Docker Generic Container Test env: ORG: ${{ secrets.DOCKERHUB_USERNAME }} IMAGE_NAME: ci-generic-debian runs-on: ubuntu-latest + strategy: + matrix: + cmd: + - rustc --version + - go version + - node --version + - ruby --version + - gcc --version + - g++ --version + - python --version steps: - name: Test Entrypoint Default run: |- { ORG_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}" printf "Testing default entrypoint\n" + printf "\n" docker run "${ORG_IMAGE}:latest" + printf "\n" + for c in $(docker ps -a | grep "${ORG_IMAGE}" | awk '{ print $1 }'); do + echo docker rm "${c}" + docker rm "${c}" + printf "\n" + done } | tee -a "${GITHUB_STEP_SUMMARY}" - - name: Test Entrypoint - Rust + - name: Test Entrypoint ${{ matrix.cmd }} run: |- { ORG_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}" - printf "Testing entrypoint - rust\n" - docker run "${ORG_IMAGE}:latest" rustc --version + printf "Testing ${{ matrix.cmd }} entrypoint\n" + printf "\n" + docker run "${ORG_IMAGE}:latest" ${{ matrix.cmd }} + printf "\n" + for c in $(docker ps -a | grep "${ORG_IMAGE}" | awk '{ print $1 }'); do + echo docker rm "${c}" + docker rm "${c}" + printf "\n" + done } | tee -a "${GITHUB_STEP_SUMMARY}" - - name: Test Entrypoint - Go - run: |- - { - ORG_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}" - printf "Testing entrypoint - go\n" - docker run "${ORG_IMAGE}:latest" go version - } | tee -a "${GITHUB_STEP_SUMMARY}" - - name: Test Entrypoint - NodeJs + - name: Docker Version run: |- - { - ORG_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}" - printf "Testing entrypoint - nodejs\n" - docker run "${ORG_IMAGE}:latest" node --version - } | tee -a "${GITHUB_STEP_SUMMARY}" - - name: Test Entrypoint - Ruby + docker version + - name: Test Entrypoint - Docker run: |- { ORG_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}" - printf "Testing entrypoint - ruby\n" - docker run "${ORG_IMAGE}:latest" ruby --version + printf "Testing entrypoint - docker\n" + printf "\n" + docker run -v /var/run/docker.sock:/var/run/docker.sock "${ORG_IMAGE}:latest" docker version + printf "\n" + for c in $(docker ps -a | grep "${ORG_IMAGE}" | awk '{ print $1 }'); do + echo docker rm "${c}" + docker rm "${c}" + printf "\n" + done } | tee -a "${GITHUB_STEP_SUMMARY}" - - name: Test Entrypoint - Gcc + stage1b: + name: Docker Anaconda Container Test + env: + ORG: ${{ secrets.DOCKERHUB_USERNAME }} + IMAGE_NAME: ci-anaconda-debian + runs-on: ubuntu-latest + strategy: + matrix: + cmd: + - gcc --version + - python --version + - R --version + - Rscript --version + steps: + - name: Test Entrypoint Default run: |- { ORG_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}" - printf "Testing entrypoint - gcc\n" - docker run "${ORG_IMAGE}:latest" gcc --version + printf "Testing default entrypoint\n" + printf "\n" + docker run "${ORG_IMAGE}:latest" + printf "\n" + for c in $(docker ps -a | grep "${ORG_IMAGE}" | awk '{ print $1 }'); do + echo docker rm "${c}" + docker rm "${c}" + printf "\n" + done } | tee -a "${GITHUB_STEP_SUMMARY}" - - name: Test Entrypoint - Python + - name: Test Entrypoint ${{ matrix.cmd }} run: |- { ORG_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}" - printf "Testing entrypoint - python\n" - docker run "${ORG_IMAGE}:latest" python --version + printf "Testing ${{ matrix.cmd }} entrypoint\n" + printf "\n" + docker run "${ORG_IMAGE}:latest" ${{ matrix.cmd }} + printf "\n" + for c in $(docker ps -a | grep "${ORG_IMAGE}" | awk '{ print $1 }'); do + echo docker rm "${c}" + docker rm "${c}" + printf "\n" + done } | tee -a "${GITHUB_STEP_SUMMARY}" - name: Docker Version run: |- @@ -86,19 +134,31 @@ jobs: { ORG_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}" printf "Testing entrypoint - docker\n" + printf "\n" docker run -v /var/run/docker.sock:/var/run/docker.sock "${ORG_IMAGE}:latest" docker version + printf "\n" + for c in $(docker ps -a | grep "${ORG_IMAGE}" | awk '{ print $1 }'); do + echo docker rm "${c}" + docker rm "${c}" + printf "\n" + done } | tee -a "${GITHUB_STEP_SUMMARY}" stage2: name: Dagger Test env: ORG: ${{ secrets.DOCKERHUB_USERNAME }} - IMAGE_NAME: ci-generic-debian + strategy: + matrix: + image: + - ci-generic-debian + - ci-anaconda-debian runs-on: ubuntu-latest steps: - name: Show dagger version run: |- { - ORG_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}" + IMAGE_NAME="${{ matrix.image }}" + ORG_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/${IMAGE_NAME}" printf "dagger version\n" docker run "${ORG_IMAGE}:latest" dagger version } |& tee -a "${GITHUB_STEP_SUMMARY}" @@ -109,17 +169,3 @@ jobs: printf "Testing entrypoint - dagger\n" docker run -v /var/run/docker.sock:/var/run/docker.sock "${ORG_IMAGE}:latest" dagger run uptime } |& tee -a "${GITHUB_STEP_SUMMARY}" - stage3: - name: Dagger Script Test - runs-on: ubuntu-latest - container: - image: vpayno/ci-generic-debian:latest - steps: - - name: Checkout Repo - uses: actions/checkout@v3 - - name: Test dagger shell cli - run: |- - { - printf "Testing dagger script\n" - .github/dagger/dagger-cli-test-ci-container.sh - } |& tee -a "${GITHUB_STEP_SUMMARY}" diff --git a/.github/workflows/r.yaml b/.github/workflows/r.yaml new file mode 100644 index 00000000..23d07f2b --- /dev/null +++ b/.github/workflows/r.yaml @@ -0,0 +1,206 @@ +--- +# +# .github/workflows/r.yml +# +name: R Workflow 4.0 +on: # yamllint disable-line rule:truthy + pull_request: + workflow_dispatch: + +defaults: + run: + shell: bash + +jobs: + stage1: + name: Change Check + runs-on: 'ubuntu-latest' + outputs: + docs_changed: ${{ steps.check_file_changed.outputs.docs_changed }} + matrix_exercise: ${{ steps.check_file_changed.outputs.matrix_exercise }} + exercise_count: ${{ steps.check_file_changed.outputs.exercise_count }} + steps: + - name: Check GitHub Vars + id: github-vars-check + run: |- + { + printf "\`\`\`text\n" + printf "Runner environment info:\n" + set | grep -e ^CI -e ^GITHUB_ -e ^RUNNER_ + printf "\`\`\`\n" + } | tee -a "${GITHUB_STEP_SUMMARY}" + - name: Check GitHub User + id: github-user-check + run: |- + # get user info for default gh container + { + printf "\`\`\`text\n" + printf "Container user info:\n" + who + printf "\n" + id + printf "\n" + printf "HOME: %s\n" "${HOME}" + printf "\n" + printf "SHELL: %s\n" "$(getent passwd "${USER}" | awk -F: '{print $NF}')" + printf "\`\`\`\n" + } | tee -a "${GITHUB_STEP_SUMMARY}" + - name: Checkout Repo + id: checkout-repo + uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: ${{ github.ref }} + submodules: recursive + - name: Get Change List + id: check_file_changed + run: |- + { + printf "Workflow: %s\n\n" "${GITHUB_WORKFLOW}" + printf "Runner: name[%s] arch[%s]\n" "${RUNNER_NAME}" "${RUNNER_ARCH}" + printf "Repo: %s\n" "${GITHUB_REPOSITORY}" + printf "User: %s\n" "${GITHUB_TRIGGERING_ACTOR}" + printf "\n" + } | tee -a "${GITHUB_STEP_SUMMARY}" + + # Diff HEAD with the previous commit then output to stdout. + GIT_DIFF="$(git diff --name-only HEAD^ HEAD | tee /tmp/changed_files.txt)" + { + printf "=== Which files changed? ===\n" + printf "\`\`\`text\n" + printf "%s\n" "${GIT_DIFF}" + printf "\`\`\`\n" + } | tee -a "${GITHUB_STEP_SUMMARY}" + HAS_WF_DIFF=false + HAS_EX_DIFF=false + if printf "%s\n" "${GIT_DIFF}" | grep -E '^(.github/workflows/r.yml|.github/citools/r/)$'; then + HAS_WF_DIFF=true + fi + if printf "%s\n" "${GIT_DIFF}" | grep -E '^r/.*[.]R$'; then + HAS_EX_DIFF=true + fi + printf "\n" + printf "=== Did WF/CI change without exercise changes? ===\n" + CI_FORCE_FULL=false + if ${HAS_WF_DIFF} && ! ${HAS_EX_DIFF}; then + CI_FORCE_FULL=true + printf "%s\n" "${CI_FORCE_FULL}" + fi + printf "\n" + + # Get changed exercise list. + if [[ ${GITHUB_EVENT_NAME} == pull_request ]] && ! ${CI_FORCE_FULL}; then + printf "Generating pull request changed exercise list.\n" + grep -E '^r/[-a-z0-9]+./.*$' /tmp/changed_files.txt | cut -f1,2 -d/ | sort -Vu | tee /tmp/exercises.txt || true + else + printf "Generating complete exercise list.\n" + find ./r/ -type d -print | grep -v -E '^[.]/r/(|[.].*)$' | sed -r -e 's:[.]/(r/[-a-z0-9]+)/?.*$:\1:g' | sort -Vu | tee /tmp/exercises.txt + HAS_DIFF=true + fi + printf "\n" + + # Check if the files are present in the changed file list (added, modified, deleted) then output to stdout. + HAS_DIFF="${HAS_DIFF:-false}" + printf "=== Which R files changed? ===\n" + if printf "%s\n" "${GIT_DIFF}" | grep -E '^(r/.*[.]R|.github/workflows/r.yml|.github/citools/r/)$'; then + HAS_DIFF=true + printf "%s\n" "${HAS_DIFF}" + fi + printf "\n" + + # Did R files change? + printf "=== Did R files change? ===\n" + printf "%s\n" "${HAS_DIFF}" + printf "\n" + + # Generate exercise job matrix from changed files list. + printf "=== Generating matrix exercise list. ===\n" + declare -i last=0 + declare -i count=0 + last=$(wc -l /tmp/exercises.txt | cut -f1 -d\ ) + ((last -= 1)) || true + entries="" + while read -r line; do + if [[ ! ${count} -lt ${last} ]]; then + comma="" + else + comma="," + fi + printf -v entry "\"%s\"%s\n" "${line}" "${comma}" + ((count += 1)) + entries+="${entry}" + done < <(sort -V /tmp/exercises.txt) + jq --sort-keys . >/tmp/exercises.json <> "${GITHUB_OUTPUT}" + check-matrix: + runs-on: ubuntu-latest + needs: stage1 + steps: + - name: Install json2yaml + run: sudo npm install -g json2yaml + - name: Check matrix::exercises + run: |- + exercise_count='${{ needs.stage1.outputs.exercise_count }}' + matrix_exercise='${{ needs.stage1.outputs.matrix_exercise }}' + { + printf "\`\`\`text\n" + printf "exercise_count=%s\n" "${exercise_count}" + printf "matrix_exercise=%s\n" "${matrix_exercise}" + printf "\`\`\`\n" + printf "json:\n" + printf "\`\`\`text\n" + printf "%s" "${matrix_exercise}" | jq . + printf "\`\`\`\n" + } | tee -a "${GITHUB_STEP_SUMMARY}" + { + printf "yaml:\n" + printf "\`\`\`text\n" + printf "{ \"matrix\": { \"exercise\": %s } }" "${matrix_exercise}" | json2yaml + printf "\`\`\`\n" + } | tee -a "${GITHUB_STEP_SUMMARY}" + stage2: + name: R Checks + strategy: + matrix: + os: ["ubuntu-latest", "windows-latest", "macos-latest"] + exclude: + - os: "macos-latest" + - os: "windows-latest" + exercise: ${{fromJson(needs.stage1.outputs.matrix_exercise)}} + runs-on: "${{ matrix.os }}" + container: + image: vpayno/ci-anaconda-debian:latest + needs: [stage1] + if: needs.stage1.outputs.docs_changed == 'true' + steps: + - name: Checkout Repo [${{ matrix.exercise }}] + id: checkout-repo + uses: actions/checkout@v3 + - name: Config R Tools [${{ matrix.exercise }}] + id: config-r-tools + run: |- + ./.github/citools/common/run_wrapper_script "./${{ matrix.exercise }}" ../../.github/citools/r/r-setup-config + - name: Show R Version [${{ matrix.exercise }}] + id: r-version + run: |- + ./.github/citools/common/run_wrapper_script "./${{ matrix.exercise }}" ../../.github/citools/r/r-setup-verify + - name: Running R Tests [${{ matrix.exercise }}] + id: r-test + run: |- + ./.github/citools/common/run_wrapper_script "./${{ matrix.exercise }}" ../../.github/citools/r/r-test diff --git a/Dockerfile b/Dockerfile index e59323e6..2c6b6799 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,27 +2,53 @@ # Dockerfile # -From debian:bookworm-slim As ci-generic-base +From debian:bookworm-slim As ci-base-debian COPY .github/docker /.github/docker COPY .github/citools/ /.github/citools/ -RUN sh .github/docker/layer-00.00-base-dependencies.sh ci-generic-debian && : 20240109-002 +RUN sh .github/docker/layer-00.00-base-dependencies.sh ci-base-debian && : 20240109-002 -RUN bash .github/docker/layer-00.01-base-env_setup.sh ci-generic-debian && : 20231103-000 +RUN bash .github/docker/layer-00.01-base-env_setup.sh ci-base-debian && : 20231103-000 -RUN bash .github/docker/layer-00.10-base-daggerio.sh ci-generic-debian && : 20231103-000 +RUN bash .github/docker/layer-00.05-additional_deps.sh ci-base-debian && : 20240329-000 -RUN bash .github/docker/layer-00.50-base-docker.sh ci-generic-debian && : 20231228-000 +RUN bash .github/docker/layer-00.10-base-daggerio.sh ci-base-debian && : 20231103-000 -RUN bash .github/docker/layer-02.00-git.sh ci-generic-debian && : 20231103-000 +RUN bash .github/docker/layer-00.50-base-docker.sh ci-base-debian && : 20231228-000 -RUN bash .github/docker/layer-09.00-exercism-nodejs.sh ci-generic-debian && : 20231103-000 +RUN bash .github/docker/layer-02.00-git.sh ci-base-debian && : 20231103-000 -RUN bash .github/docker/layer-10.00-exercism-gcc_clang_llvm.sh ci-generic-debian && : 20231103-000 +RUN bash .github/docker/layer-09.00-exercism-nodejs.sh ci-base-debian && : 20231103-000 -RUN bash .github/docker/layer-14.00-exercism-tools.sh ci-generic-debian && : 20240101-000 +RUN bash .github/docker/layer-10.00-exercism-gcc_clang_llvm.sh ci-base-debian && : 20231103-000 + +RUN bash .github/docker/layer-14.00-exercism-tools.sh ci-base-debian && : 20240101-000 + +RUN bash .github/docker/layer-99.00-summary.sh ci-base-debian && : 20231103-000 + +# Copies your code file from your action repository to the filesystem path `/` of the container +COPY .github/docker/entrypoint.sh /entrypoint.sh + +RUN rm -rvf /.github + +SHELL ["bash", "-c"] + +# app + args +# Executes `entrypoint.sh` when the Docker container starts up +ENTRYPOINT ["/entrypoint.sh"] + +# Extra args +CMD [] + +# ============================================================================= + +From ci-base-debian As ci-generic-debian + +COPY .github/docker /.github/docker + +COPY .github/citools/ /.github/citools/ RUN bash .github/docker/layer-15.00-exercism-rust.sh ci-generic-debian && : 20231103-000 @@ -53,3 +79,35 @@ ENTRYPOINT ["/entrypoint.sh"] # Extra args CMD [] + +# ============================================================================= + +From ci-base-debian As ci-anaconda-debian + +COPY .github/docker /.github/docker + +COPY .github/citools/ /.github/citools/ + +RUN bash .github/docker/layer-18.00-exercism-python.sh ci-anaconda-debian && : 20240322-000 + +RUN bash .github/docker/layer-20.00-exercism-r.sh ci-anaconda-debian && : 20240328-000 + +RUN bash .github/docker/layer-25.00-tools-vscode.sh ci-anaconda-debian && : 20240102-000 + +RUN bash .github/docker/layer-35.00-tools-tailscale.sh ci-anaconda-debian && : 20240111-000 + +RUN bash .github/docker/layer-99.00-summary.sh ci-anaconda-debian && : 20231103-000 + +# Copies your code file from your action repository to the filesystem path `/` of the container +COPY .github/docker/entrypoint.sh /entrypoint.sh + +RUN rm -rvf /.github + +SHELL ["bash", "-c"] + +# app + args +# Executes `entrypoint.sh` when the Docker container starts up +ENTRYPOINT ["/entrypoint.sh"] + +# Extra args +CMD [] diff --git a/README.md b/README.md index 29b5cbca..ee3cd59f 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Archived `#12in23` challenge notes to [README-2023.md](./README-2023.md) [![Ruby Workflow](https://github.com/vpayno/exercism-workspace/actions/workflows/ruby.yml/badge.svg)](https://github.com/vpayno/exercism-workspace/actions/workflows/ruby.yml) [![WebAssembly Workflow](https://github.com/vpayno/exercism-workspace/actions/workflows/wasm.yml/badge.svg)](https://github.com/vpayno/exercism-workspace/actions/workflows/wasm.yml) [![Gleam Workflow](https://github.com/vpayno/exercism-workspace/actions/workflows/gleam.yml/badge.svg)](https://github.com/vpayno/exercism-workspace/actions/workflows/gleam.yml) +[![R Workflow](https://github.com/vpayno/exercism-workspace/actions/workflows/r.yml/badge.svg)](https://github.com/vpayno/exercism-workspace/actions/workflows/r.yml) [![Git PR Checks](https://github.com/vpayno/exercism-workspace/actions/workflows/git-pr.yml/badge.svg)](https://github.com/vpayno/exercism-workspace/actions/workflows/git-pr.yml) [![Check Links](https://github.com/vpayno/exercism-workspace/actions/workflows/links.yml/badge.svg)](https://github.com/vpayno/exercism-workspace/actions/workflows/links.yml) @@ -70,6 +71,7 @@ Archived `#12in23` challenge notes to [README-2023.md](./README-2023.md) - [Ruby Workflow](.github/workflows/ruby.yml) - [WebAssembly Workflow](.github/workflows/wasm.yml) - [Gleam Workflow](.github/workflows/gleam.yml) +- [R Workflow](.github/workflows/r.yml) - [Link Checker Workflow](.github/workflows/links.yml) - [CodeQL Workflow](.github/workflows/codeql-analysis.yml) - [Woke PR](.github/workflows/woke-pr.yml) @@ -94,6 +96,7 @@ Archived `#12in23` challenge notes to [README-2023.md](./README-2023.md) - [Ruby](ruby/README.md) - [WebAssembly](wasm/README.md) - [Gleam](gleam/README.md) +- [R](r/README.md) ## Tools/Scripts @@ -114,3 +117,4 @@ Archived `#12in23` challenge notes to [README-2023.md](./README-2023.md) - [Ruby run-tests](./ruby/run-tests) - [WebAssembly run-tests](./wasm/run-tests) - [Gleam run-tests](./gleam/run-tests) +- [R run-tests](./r/run-tests) diff --git a/r/.python-version b/r/.python-version new file mode 100644 index 00000000..c931778c --- /dev/null +++ b/r/.python-version @@ -0,0 +1 @@ +anaconda3 diff --git a/r/README.md b/r/README.md new file mode 100644 index 00000000..f0d051f9 --- /dev/null +++ b/r/README.md @@ -0,0 +1,15 @@ +# Exercism R Track + +[Home Page](https://exercism.org/tracks/r + +[My Profile](https://exercism.org/profiles/vpayno) + +## Tools + +- [for_each](./for_each) +- [run-tests](./run-tests) +- [submit_files](./submit_files) +- [update_readmes](./update_readmes) + +## [Exercises](https://exercism.org/tracks/r/exercises) + diff --git a/r/for_each b/r/for_each new file mode 100755 index 00000000..717b1149 --- /dev/null +++ b/r/for_each @@ -0,0 +1,24 @@ +#!/bin/bash + +declare -i retval=0 +declare pkg_name +declare d + +time for d in ./*; do + [[ -d ${d} ]] || continue + cd "${d}" || continue + printf "[dir: %s]\n\n" "${PWD}" + + pkg_name="$(basename "${PWD}")" + + printf "[pkg: %s]\n\n" "${pkg_name}" + + echo "${@}" + time "${@}" || ((retval++)) + + printf "\n" + + cd - || break +done + +exit "${retval}" diff --git a/r/hello-world/.exercism/config.json b/r/hello-world/.exercism/config.json new file mode 100644 index 00000000..c0f9df63 --- /dev/null +++ b/r/hello-world/.exercism/config.json @@ -0,0 +1,25 @@ +{ + "authors": [ + "jonboiser" + ], + "contributors": [ + "jonmcalder", + "katrinleinweber", + "ttnagata", + "zacchaeusluke" + ], + "files": { + "solution": [ + "hello-world.R" + ], + "test": [ + "test_hello-world.R" + ], + "example": [ + ".meta/example.R" + ] + }, + "blurb": "Exercism's classic introductory exercise. Just say \"Hello, World!\".", + "source": "This is an exercise to introduce users to using Exercism", + "source_url": "https://en.wikipedia.org/wiki/%22Hello,_world!%22_program" +} diff --git a/r/hello-world/.exercism/metadata.json b/r/hello-world/.exercism/metadata.json new file mode 100644 index 00000000..dab264c5 --- /dev/null +++ b/r/hello-world/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"r","exercise":"hello-world","id":"3a94be348ffc40bbb1f287433eaa4fb2","url":"https://exercism.org/tracks/r/exercises/hello-world","handle":"vpayno","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/r/hello-world/HELP.md b/r/hello-world/HELP.md new file mode 100644 index 00000000..13d19857 --- /dev/null +++ b/r/hello-world/HELP.md @@ -0,0 +1,38 @@ +# Help + +## Running the tests + +Tests require the `{testthat}` package to be installed in R. +To run the tests for an exercise, simply execute the `test_.R` script from within the exercise's directory. + +This can be conveniently done with [testthat's `auto_test` function](https://testthat.r-lib.org/reference/auto_test.html). Because exercism code and tests are in the same folder, use this same path for both `code_path` and `test_path` parameters. On the command-line, you can also run `Rscript test_.R`. + +See the [tests page](https://exercism.org/docs/tracks/r/tests) for more information. + +## Submitting your solution + +You can submit your solution using the `exercism submit hello-world.R` command. +This command will upload your solution to the Exercism website and print the solution page's URL. + +It's possible to submit an incomplete solution which allows you to: + +- See how others have completed the exercise +- Request help from a mentor + +## Need to get help? + +If you'd like help solving the exercise, check the following pages: + +- The [R track's documentation](https://exercism.org/docs/tracks/r) +- The [R track's programming category on the forum](https://forum.exercism.org/c/programming/r) +- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can try one of the following resources: + +- [StackOverflow](https://stackoverflow.com/questions/tagged/r) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions. +- [#rstats](https://twitter.com/search?q=%23rstats) is the hashtag to use if you are asking for help or guidance on Twitter. The R community is very active on Twitter and always try to help those who are new to R. +- [/r/rstats](https://www.reddit.com/r/rstats) is the R subreddit. +- [RStudio Community](https://community.rstudio.com/) is another active and helpful R community. \ No newline at end of file diff --git a/r/hello-world/README.md b/r/hello-world/README.md new file mode 100644 index 00000000..00155baf --- /dev/null +++ b/r/hello-world/README.md @@ -0,0 +1,38 @@ +# Hello World + +Welcome to Hello World on Exercism's R Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +The classical introductory exercise. +Just say "Hello, World!". + +["Hello, World!"][hello-world] is the traditional first program for beginning programming in a new language or environment. + +The objectives are simple: + +- Modify the provided code so that it produces the string "Hello, World!". +- Run the test suite and make sure that it succeeds. +- Submit your solution and check it at the website. + +If everything goes well, you will be ready to fetch your first real exercise. + +[hello-world]: https://en.wikipedia.org/wiki/%22Hello,_world!%22_program + +## Source + +### Created by + +- @jonboiser + +### Contributed to by + +- @jonmcalder +- @katrinleinweber +- @ttnagata +- @zacchaeusluke + +### Based on + +This is an exercise to introduce users to using Exercism - https://en.wikipedia.org/wiki/%22Hello,_world!%22_program \ No newline at end of file diff --git a/r/hello-world/hello-world.R b/r/hello-world/hello-world.R new file mode 100644 index 00000000..50696d0c --- /dev/null +++ b/r/hello-world/hello-world.R @@ -0,0 +1,3 @@ +hello_world <- function() { + "Hello, World!" +} diff --git a/r/hello-world/run-tests-r.txt b/r/hello-world/run-tests-r.txt new file mode 100644 index 00000000..73780837 --- /dev/null +++ b/r/hello-world/run-tests-r.txt @@ -0,0 +1,62 @@ +Running automated test file(s): + + +=============================================================================== + +Running: ../../.github/citools/r/r-test + +Running R Tests + +R versions: + + R version 4.3.3 (2024-02-29) -- "Angel Food Cake" + Copyright (C) 2024 The R Foundation for Statistical Computing + Platform: x86_64-pc-linux-gnu (64-bit) + + R is free software and comes with ABSOLUTELY NO WARRANTY. + You are welcome to redistribute it under the terms of the + GNU General Public License versions 2 or 3. + For more information about these matters see + https://www.gnu.org/licenses/. + + + Rscript (R) version 4.3.3 (2024-02-29) + + + ============================================================================== + +Running: Rscript test_hello-world.R + +Test passed 🎊 + +real 0m0.494s +user 0m0.462s +sys 0m0.033s + + + ============================================================================== + +Exit code: 0 + +real 0m0.668s +user 0m0.543s +sys 0m0.135s + +real 0m0.674s +user 0m0.548s +sys 0m0.135s + +=============================================================================== + +Running: misspell ./hello-world.R ./test_hello-world.R + +real 0m0.018s +user 0m0.022s +sys 0m0.008s + +=============================================================================== + +/home/vpayno/git_vpayno/exercism-workspace/r + +=============================================================================== + diff --git a/r/hello-world/test_hello-world.R b/r/hello-world/test_hello-world.R new file mode 100644 index 00000000..20566102 --- /dev/null +++ b/r/hello-world/test_hello-world.R @@ -0,0 +1,6 @@ +source("./hello-world.R") +library(testthat) + +test_that("no name", { + expect_equal(hello_world(), "Hello, World!") +}) diff --git a/r/run-tests b/r/run-tests new file mode 100755 index 00000000..e7b5951d --- /dev/null +++ b/r/run-tests @@ -0,0 +1,31 @@ +#!/bin/bash + +print_ruler() { + printf "\n" + printf "=%.0s" {1..79} + printf "\n" + printf "\n" +} # print_ruler() + +main() { + printf "Running automated test file(s):\n\n" + + print_ruler + + echo Running: ../../.github/citools/r/r-test + time ../../.github/citools/r/r-test + + print_ruler + + echo Running: misspell ./*.R + time misspell ./*.R + + print_ruler + + cd .. + pwd + + print_ruler +} # main() + +time main "$@" |& tee ./run-tests-r.txt diff --git a/r/submit_files b/r/submit_files new file mode 100755 index 00000000..325580b3 --- /dev/null +++ b/r/submit_files @@ -0,0 +1,41 @@ +#!/bin/bash + +if [[ ! -d .exercism ]]; then + printf "ERROR: Run from inside a project directory.\n\n" + exit 1 +fi + +# declare package_name_snake + +get_track_package_name() { + # these are kebab-case + basename "${PWD}" +} # get_track_package_name() + +kebab_case_to_pascal_case() { + printf "%s" "${@}" | sed -r -e 's/(^|[-])(\w)/\U\2/g' +} # kebab_case_to_pascal_case() + +kebab_case_to_camel_case() { + printf "%s" "${@}" | sed -r -e 's/([-])(\w)/\U\2/g' +} # kebab_case_to_camel_case() + +kebab_case_to_snake_case() { + printf "%s" "${@}" | sed -r -e 's/(\w)([-])(\w)/\1_\3/g' +} # kebab_case_to_snake_case() + +# package_name_snake="$(kebab_case_to_snake_case "$(get_track_package_name)")" + +declare -a R_FILES + +mapfile -t R_FILES < <(jq -r '.files.solution[]' .exercism/config.json) +R_FILES+=(./run-tests-r.txt) + +# mapfile -t R_FILES < <( +# find . -type f -name "*[.]go" | grep -v "_test[.]go" +# find . -type f -name "*_examples_test[.]go" +#) + +echo Running: exercism submit "${R_FILES[@]}" +time exercism submit "${R_FILES[@]}" +printf "\n" diff --git a/r/update_readmes b/r/update_readmes new file mode 100755 index 00000000..38bdac5e --- /dev/null +++ b/r/update_readmes @@ -0,0 +1,72 @@ +#!/bin/bash + +shopt -s nullglob + +if [[ ! -d .exercism ]]; then + printf "ERROR: Run from inside a project directory.\n\n" + exit 1 +fi + +#declare package_name +declare project_dir + +get_track_package_name() { + basename "${PWD}" +} # get_track_package_name() + +#package_name="$(get_track_package_name)" +project_dir="$(basename "${PWD}")" + +if ! grep -q ./"${project_dir}"/README.md ../README.md; then + + cat >>../README.md <>./README.md <>./README.md <