shuf: Fix off-by-one errors in range handling #2074
Workflow file for this run
This file contains 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: Code Quality | |
# spell-checker:ignore TERMUX reactivecircus Swatinem noaudio pkill swiftshader dtolnay juliangruber | |
on: | |
pull_request: | |
push: | |
branches: | |
- main | |
env: | |
# * style job configuration | |
STYLE_FAIL_ON_FAULT: true ## (bool) fail the build if a style job contains a fault (error or warning); may be overridden on a per-job basis | |
permissions: | |
contents: read # to fetch code (actions/checkout) | |
# End the current execution if there is a new changeset in the PR. | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
jobs: | |
style_format: | |
name: Style/format | |
runs-on: ${{ matrix.job.os }} | |
strategy: | |
fail-fast: false | |
matrix: | |
job: | |
- { os: ubuntu-latest , features: feat_os_unix } | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@master | |
with: | |
toolchain: stable | |
components: rustfmt | |
- uses: Swatinem/rust-cache@v2 | |
- name: Initialize workflow variables | |
id: vars | |
shell: bash | |
run: | | |
## VARs setup | |
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } | |
# failure mode | |
unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in | |
''|0|f|false|n|no|off) FAULT_TYPE=warning ;; | |
*) FAIL_ON_FAULT=true ; FAULT_TYPE=error ;; | |
esac; | |
outputs FAIL_ON_FAULT FAULT_TYPE | |
# target-specific options | |
# * CARGO_FEATURES_OPTION | |
CARGO_FEATURES_OPTION='' ; | |
if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi | |
outputs CARGO_FEATURES_OPTION | |
- name: "`cargo fmt` testing" | |
shell: bash | |
run: | | |
## `cargo fmt` testing | |
unset fault | |
fault_type="${{ steps.vars.outputs.FAULT_TYPE }}" | |
fault_prefix=$(echo "$fault_type" | tr '[:lower:]' '[:upper:]') | |
# * convert any errors/warnings to GHA UI annotations; ref: <https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message> | |
S=$(cargo fmt -- --check) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s\n" "$S" | sed -E -n -e "s/^Diff[[:space:]]+in[[:space:]]+${PWD//\//\\/}\/(.*)[[:space:]]+at[[:space:]]+[^0-9]+([0-9]+).*$/::${fault_type} file=\1,line=\2::${fault_prefix}: \`cargo fmt\`: style violation (file:'\1', line:\2; use \`cargo fmt -- \"\1\"\`)/p" ; fault=true ; } | |
if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi | |
style_lint: | |
name: Style/lint | |
runs-on: ${{ matrix.job.os }} | |
env: | |
SCCACHE_GHA_ENABLED: "true" | |
RUSTC_WRAPPER: "sccache" | |
strategy: | |
fail-fast: false | |
matrix: | |
job: | |
- { os: ubuntu-latest , features: feat_os_unix } | |
- { os: macos-latest , features: feat_os_macos } | |
- { os: windows-latest , features: feat_os_windows } | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@master | |
with: | |
toolchain: stable | |
components: clippy | |
- uses: Swatinem/rust-cache@v2 | |
- name: Run sccache-cache | |
uses: mozilla-actions/sccache-action@v0.0.4 | |
- name: Initialize workflow variables | |
id: vars | |
shell: bash | |
run: | | |
## VARs setup | |
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } | |
# failure mode | |
unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in | |
''|0|f|false|n|no|off) FAULT_TYPE=warning ;; | |
*) FAIL_ON_FAULT=true ; FAULT_TYPE=error ;; | |
esac; | |
outputs FAIL_ON_FAULT FAULT_TYPE | |
# target-specific options | |
# * CARGO_FEATURES_OPTION | |
CARGO_FEATURES_OPTION='--all-features' ; | |
if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features ${{ matrix.job.features }}' ; fi | |
outputs CARGO_FEATURES_OPTION | |
# * determine sub-crate utility list | |
UTILITY_LIST="$(./util/show-utils.sh ${CARGO_FEATURES_OPTION})" | |
echo UTILITY_LIST=${UTILITY_LIST} | |
CARGO_UTILITY_LIST_OPTIONS="$(for u in ${UTILITY_LIST}; do echo -n "-puu_${u} "; done;)" | |
outputs CARGO_UTILITY_LIST_OPTIONS | |
- name: Install/setup prerequisites | |
shell: bash | |
run: | | |
## Install/setup prerequisites | |
case '${{ matrix.job.os }}' in | |
macos-latest) brew install coreutils ;; # needed for show-utils.sh | |
esac | |
- name: "`cargo clippy` lint testing" | |
shell: bash | |
run: | | |
## `cargo clippy` lint testing | |
unset fault | |
CLIPPY_FLAGS="-W clippy::default_trait_access -W clippy::manual_string_new -W clippy::cognitive_complexity -W clippy::implicit_clone -W clippy::range-plus-one -W clippy::redundant-clone" | |
fault_type="${{ steps.vars.outputs.FAULT_TYPE }}" | |
fault_prefix=$(echo "$fault_type" | tr '[:lower:]' '[:upper:]') | |
# * convert any warnings to GHA UI annotations; ref: <https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message> | |
S=$(cargo clippy --all-targets ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_UTILITY_LIST_OPTIONS }} -- ${CLIPPY_FLAGS} -D warnings 2>&1) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n -e '/^error:/{' -e "N; s/^error:[[:space:]]+(.*)\\n[[:space:]]+-->[[:space:]]+(.*):([0-9]+):([0-9]+).*$/::${fault_type} file=\2,line=\3,col=\4::${fault_prefix}: \`cargo clippy\`: \1 (file:'\2', line:\3)/p;" -e '}' ; fault=true ; } | |
if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi | |
style_spellcheck: | |
name: Style/spelling | |
runs-on: ${{ matrix.job.os }} | |
strategy: | |
matrix: | |
job: | |
- { os: ubuntu-latest , features: feat_os_unix } | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Initialize workflow variables | |
id: vars | |
shell: bash | |
run: | | |
## VARs setup | |
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } | |
# failure mode | |
unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in | |
''|0|f|false|n|no|off) FAULT_TYPE=warning ;; | |
*) FAIL_ON_FAULT=true ; FAULT_TYPE=error ;; | |
esac; | |
outputs FAIL_ON_FAULT FAULT_TYPE | |
- name: Install/setup prerequisites | |
shell: bash | |
run: | | |
sudo apt-get -y update ; sudo apt-get -y install npm ; sudo npm install cspell -g ; | |
- name: Run `cspell` | |
shell: bash | |
run: | | |
## Run `cspell` | |
unset fault | |
fault_type="${{ steps.vars.outputs.FAULT_TYPE }}" | |
fault_prefix=$(echo "$fault_type" | tr '[:lower:]' '[:upper:]') | |
# * find cspell configuration ; note: avoid quotes around ${cfg_file} b/c `cspell` (v4) doesn't correctly dequote the config argument (or perhaps a subshell expansion issue?) | |
cfg_files=($(shopt -s nullglob ; echo {.vscode,.}/{,.}c[sS]pell{.json,.config{.js,.cjs,.json,.yaml,.yml},.yaml,.yml} ;)) | |
cfg_file=${cfg_files[0]} | |
unset CSPELL_CFG_OPTION ; if [ -n "$cfg_file" ]; then CSPELL_CFG_OPTION="--config $cfg_file" ; fi | |
S=$(cspell ${CSPELL_CFG_OPTION} --no-summary --no-progress "**/*") && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n "s/${PWD//\//\\/}\/(.*):(.*):(.*) - (.*)/::${fault_type} file=\1,line=\2,col=\3::${fault_type^^}: \4 (file:'\1', line:\2)/p" ; fault=true ; true ; } | |
if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi | |
toml_format: | |
name: Style/toml | |
runs-on: ubuntu-latest | |
steps: | |
- name: Clone repository | |
uses: actions/checkout@v4 | |
- name: Check | |
run: npx --yes @taplo/cli fmt --check |