File retry-1737025645.819c129.obscpio of Package retry

07070100000000000041FD0000000000000000000000016788E86D00000000000000000000000000000000000000000000002100000000retry-1737025645.819c129/.github07070100000001000041FD0000000000000000000000016788E86D00000000000000000000000000000000000000000000002B00000000retry-1737025645.819c129/.github/workflows07070100000002000081B40000000000000000000000016788E86D000001CA000000000000000000000000000000000000003200000000retry-1737025645.819c129/.github/workflows/ci.yml---
name: ci
# yamllint disable-line rule:truthy
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: unit tests
        run: |
         make test-unit

  style:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Static checks
        run: |
         sudo apt-get install shellcheck
         export PATH=.:$PATH
         make checkbashisms checkstyle
07070100000003000081B40000000000000000000000016788E86D00000020000000000000000000000000000000000000002400000000retry-1737025645.819c129/.gitignore/test-more-bash/
/checkbashisms
07070100000004000081B40000000000000000000000016788E86D0000027C000000000000000000000000000000000000002600000000retry-1737025645.819c129/.mergify.yml---
pull_request_rules:
  - name: automatic merge
    conditions:
      - and: &base_checks
        - base=main
        - -label~=^acceptance-tests-needed|not-ready
        - "status-success~=test"
        - "status-success~=style"
      - and:
        - "#approved-reviews-by>=1"
        - "#changes-requested-reviews-by=0"
        # https://doc.mergify.io/examples.html#require-all-requested-reviews-to-be-approved
        - "#review-requested=0"
    actions: &merge
      merge:
        method: merge
  - name: automatic merge on special label
    conditions:
      - and: *base_checks
      - "label=merge-fast"
    actions: *merge
07070100000005000081B40000000000000000000000016788E86D00000436000000000000000000000000000000000000002100000000retry-1737025645.819c129/LICENSEMIT License

Copyright Oliver Kurz
Copyright SUSE LLC

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
07070100000006000081B40000000000000000000000016788E86D0000060D000000000000000000000000000000000000002200000000retry-1737025645.819c129/Makefile.PHONY: all
all:

.PHONY: test
test: checkstyle test-unit

.PHONY: test-unit
test-unit: test-more-bash
	@command -v prove >/dev/null 2>&1 || echo "Command 'git' not found, can not get test-more-bash to execute tests"
	prove -r test/

test-more-bash:
	@command -v git >/dev/null 2>&1 || echo "Command 'git' not found, can not get test-more-bash to execute tests"
	git clone https://github.com/ingydotnet/test-more-bash.git --depth 1 -b 0.0.5

checkbashisms:
	@command -v wget >/dev/null 2>&1 || echo "Command 'wget' not found, can not download checkbashisms"
	wget -q https://salsa.debian.org/debian/devscripts/-/raw/main/scripts/checkbashisms.pl -O checkbashisms
	chmod +x checkbashisms
	command -v checkbashisms >/dev/null || echo "Downloaded checkbashisms. You can check the file and add to PATH, then call make again"

.PHONY: checkstyle
checkstyle: test-shellcheck test-checkbashisms

.PHONY: test-shellcheck
test-shellcheck:
	@command -v shellcheck >/dev/null 2>&1 || echo "Command 'shellcheck' not found, can not execute shell script checks"
	shellcheck -x $$(file --mime-type * | sed -n 's/^\(.*\):.*text\/x-shellscript.*$$/\1/p')

.PHONY: test-checkbashisms
test-checkbashisms:
	@command -v checkbashisms >/dev/null 2>&1 || echo "Command 'checkbashisms' not found, can not execute shell script checks"
	checkbashisms -x $$(file --mime-type * | sed -n 's/^\(.*\):.*text\/x-shellscript.*$$/\1/p')

.PHONY: install
install:
	install -m 755 retry "$(DESTDIR)"/usr/bin/retry
	install -m 755 count-fail-ratio "$(DESTDIR)"/usr/bin/count-fail-ratio
07070100000007000081B40000000000000000000000016788E86D00000A01000000000000000000000000000000000000002300000000retry-1737025645.819c129/README.md# retry ![](https://github.com/okurz/retry/workflows/ci/badge.svg)

A simply retry tool in plain POSIX sh.


## How to use

Simply call

```
retry $cmd
```

to execute `$cmd` and on failure retry multiple times with some waiting time
between calls. Multiple command line parameters exist to tweak execution.

It is possible to specify no waiting time if desired:

```
retry -s 0 $cmd
```

If it is necessary to specify command line parameters to `$cmd` separate the
arguments with `--` like this:

```
retry -- $cmd --my-argument -X 3
```

Often it is desired to command the execution with a timeout. This can be done
with the `timeout` command from [GNU
coreutils](https://www.gnu.org/software/coreutils/) already present on many
systems. Either use with a global timeout:

```
timeout 10 retry $cmd
```

to execute `$cmd` with retrying but only wait up to 10s in total. Or with a
timeout per execution:

```
retry -- timeout 10 $cmd
```

### count-fail-ratio - simple statistics about retries

Another tool provided is "count-fail-ratio" which can count fails, the fail
ratio, the failure probability and timing information from repeated command
calls. Simply call

```
count-fail-ratio $cmd
```

to execute `$cmd` automatically multiple times collecting the mentioned
statistics.

Further options to count-fail-ratio can be specified by runtime variables. For
example to change the number of runs from the default of 20 set the variable
"runs" while disabling computing timing information:

```
runs=100 timing=0 count-fail-ratio $cmd
```

For the complete list of variables take a look into the script file
count-fail-ratio itself.

## Contribute

This project lives in https://github.com/okurz/retry

Feel free to add issues in github or send pull requests.

### Rules for commits

* For git commit messages use the rules stated on
  [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) as
  a reference

If this is too much hassle for you feel free to provide incomplete pull
requests for consideration or create an issue with a code change proposal.

### Local testing

#### Functional testing

This is done with the [Test::More bash
library](https://github.com/ingydotnet/test-more-bash).
It will be automatically cloned.


To execute tests call

```
make test
```

#### Style checks

```
make checkstyle
```

## Alternatives

* https://github.com/minfrin/retry - an older C implementation which is also
  available in Debian and Ubuntu.

## License

This project is licensed under the MIT license, see LICENSE file for details.
07070100000008000081FD0000000000000000000000016788E86D000006C0000000000000000000000000000000000000002A00000000retry-1737025645.819c129/count-fail-ratio#!/bin/bash -e
# shellcheck disable=SC2048
[ "$1" = "-h" ] || [ "$1" = "--help" ] && echo "Run an arbitrary command multiple times and count failures and fail ratio" && exit

fails="${fails:-0}"
runs="${runs:-"20"}"
start="${start:-1}"
timing="${timing:-1}"
if [ "$timing" = 1 ]; then t_start=$(date +%s%N); fi
declare -a times=()
for ((i=start; i <= runs; i++)); do
    echo "## Run $i"
    if [ "$timing" = 1 ]; then t_run_start=$(date +%s%N); fi
    "$@" || fails=$((fails+1))
    if [ "$timing" = 1 ]; then
        t_run_end=$(date +%s%N)
        runtime=$(( (t_run_end - t_run_start) / 1000000 ))
        times+=("$runtime")
    fi
    p=$(bc <<< "scale=9;${fails}/${i}")
    standard_error=$(bc <<< "scale=9;sqrt(${p}*(1 - ${p})/${i})")
    # critical value (z_value) for a 95% confidence level. In this
    # case, the critical value is approximately 1.96.
    z_value=1.96
    me=$(bc <<< "scale=9;${z_value}*${standard_error}")
    echo -n "## $(basename "$0"): Run: $i. Fails: $fails. Fail ratio $(bc <<< "r=${p} * 100;scale=2;r/1")±$(bc <<< "r=${me}*100;scale=2;r/1")%"
    [[ $fails = 0 ]] && echo -n ". No fails, computed failure probability < $(bc <<< "scale=2;3 * 100/${i}")%"
    echo ""
    if [ "$timing" = 1 ]; then
        t_end=$(date +%s%N)
        # Compute standard deviation
        sum=0
        for time in "${times[@]}"; do
            sum=$((sum + time))
        done
        mean=$((sum / i))
        variance=0
        for time in "${times[@]}"; do
            diff=$((time - mean))
            variance=$((variance + diff*diff))
        done
        stddev=$(bc <<< "scale=2;sqrt(${variance}/${i})")
        echo "## mean runtime: $(( (t_end - t_start) / i / 1000000 ))±$stddev ms"
    fi
done
07070100000009000041FD0000000000000000000000016788E86D00000000000000000000000000000000000000000000001E00000000retry-1737025645.819c129/dist0707010000000A000041FD0000000000000000000000016788E86D00000000000000000000000000000000000000000000002200000000retry-1737025645.819c129/dist/rpm0707010000000B000081B40000000000000000000000016788E86D000004E3000000000000000000000000000000000000002D00000000retry-1737025645.819c129/dist/rpm/retry.spec#
# spec file for package retry
#
# Copyright SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.

# Please submit bugfixes or comments via http://bugs.opensuse.org/
#

Name:           retry
Version:        1
Release:        0
Summary:        A simple tool for retrying command executions in plain POSIX sh
License:        MIT
Group:          Development/Tools/Other
BuildArch:      noarch
Url:            https://github.com/okurz/retry
Source0:        %{name}-%{version}.tar.xz
Requires:       util-linux

%description
A simple tool for retrying command executions in plain POSIX sh.

%prep
%setup -q

%build

%install
mkdir -p %{buildroot}%{_bindir}
%make_install

%check

%files
%{_bindir}/retry
%{_bindir}/count-fail-ratio

%changelog
0707010000000C000081FD0000000000000000000000016788E86D00000671000000000000000000000000000000000000001F00000000retry-1737025645.819c129/retry#!/bin/sh -e

usage() {
    echo "usage: $0 [options] [cmd...]
options:
    -h,--help                   Show this help
    -r,--retries=RETRIES        How many retries to do on command failure after
                                the initial try. Set -1 for infinite retries.
                                Defaults to 3.
    -s,--sleep=SLEEP            How many seconds to sleep between retries.
                                Defaults to 3 seconds.
    -e,--exponential[=FACTOR]   Enable simple exponential back-off algorithm.
                                Disabled by default, factor defaults to 2
                                (binary exponential back-off).
    "
}

# parse arguments
opts=$(getopt \
    --options +h,r:,s:,e:: \
    --longoptions help,retries:,sleep:,exponential:: \
    --name "$(basename "$0")" -- "$@") || { usage ; exit 1; }

eval set -- "$opts"

while [ $# -gt 0 ]; do
  case "$1" in
    -h | --help        ) usage; exit 0 ;;
    -r | --retries     ) retries=$2; shift 2 ;;
    -s | --sleep       ) sleep=$2; shift 2 ;;
    -e | --exponential ) exponential=${2:-2}; shift 2 ;;
    --                 ) shift; break ;;
    *                  ) break ;;
  esac
done

retries="${retries:-3}"
sleep="${sleep:-3}"

ret=0
retries_msg=""
while true; do
    ret=0
    "$@" && exit
    ret=$?
    if [ "$retries" = 0 ]; then
        break
    elif [ "$retries" != -1 ]; then
        retries_msg="up to $retries more times "
        retries=$((retries-1))
    fi
    echo "Retrying ${retries_msg}after sleeping ${sleep}s …" >&2
    sleep "$sleep"
    [ -n "$exponential" ] && sleep=$((sleep*exponential))
done

exit "$ret"
0707010000000D000041FD0000000000000000000000016788E86D00000000000000000000000000000000000000000000001E00000000retry-1737025645.819c129/test0707010000000E000081FD0000000000000000000000016788E86D0000055B000000000000000000000000000000000000003400000000retry-1737025645.819c129/test/01-count-fail-ratio.t#!/usr/bin/env bash

set -e
dir=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)

TEST_MORE_PATH=$dir/../test-more-bash
BASHLIB="`
    find $TEST_MORE_PATH -type d |
    grep -E '/(bin|lib)$' |
    xargs -n1 printf "%s:"`"
PATH=$BASHLIB$PATH

source bash+ :std
use Test::More
plan tests 9

call_cmd() {
    $dir/../count-fail-ratio $*
}

rc=0
output=$(runs=3 call_cmd true 2>&1) || rc=$?
is "$rc" 0 'successful run for no fails'
like "$output" 'Run: 3. Fails: 0. Fail ratio 0.*%. No fails, computed failure probability < 100.00%' 'counted all successes'

rc=0
output=$(runs=30 call_cmd true 2>&1) || rc=$?
is "$rc" 0 'successful run for many no fails'
like "$output" 'Run: 30. Fails: 0. Fail ratio 0.*%.*< 10.00%' 'computed failure probability lowers to < 10% for enough runs'

rc=0
output=$(runs=3 call_cmd false 2>&1) || rc=$?
is "$rc" 0 'successful run for all fails'
like "$output" 'count-fail-ratio: Run: 3. Fails: 3. Fail ratio 100.00.*%' 'counted all fails'

rc=0
tmp="${tmp:-"/tmp/tmp.fail-once-every-third-call"}"
echo 0 > $tmp
output=$(runs=10 call_cmd $dir/fail-once-every-third-call 2>&1) || rc=$?
is "$rc" 0 'successful run for sporadically failing script'
like "$output" 'count-fail-ratio: Run: 10. Fails: 3. Fail ratio 30.00±28.40%' 'counted sporadic failure'

output=$(runs=1 timing=1 call_cmd false 2>&1)
like "$output" 'mean runtime' 'timing info shows up'
0707010000000F000081FD0000000000000000000000016788E86D000007A1000000000000000000000000000000000000002900000000retry-1737025645.819c129/test/01-retry.t#!/usr/bin/env bash

set -e

dir=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)

TEST_MORE_PATH=$dir/../test-more-bash
BASHLIB="`
    find $TEST_MORE_PATH -type d |
    grep -E '/(bin|lib)$' |
    xargs -n1 printf "%s:"`"
PATH=$BASHLIB$PATH

source bash+ :std
use Test::More
plan tests 18

PATH=$dir/..:$PATH

sleep() { :;}
export -f sleep

ok "$(retry)" 'retry without parameter is ok'
like "$(retry --help)" usage: 'retry help is shown'
ok $? 'calling help returns success'
set +e; out=$(retry --unknown-option 2>&1); rc=$?; set -e
is $rc 1 'calling with unknown option returns failure'
like "$out" 'unrecognized option.*usage:' 'retry help is shown for unknown option'
ok "$(retry -s 0 true)" 'successful command returns success'
is "$(retry -s 0 true)" '' 'successful command does not show any output by default'
set +e; out=$(retry -s 0 false 2>&1); rc=$?; set -e
like "$out" 'Retrying up to 3 more.*Retrying up to 1' 'failing command retries'
is $rc 1 'failing command returns no success'
set +e; out=$(retry -s 1 -e -r 2 false 2>&1); rc=$?; set -e
like "$out" 'sleeping 1s.*sleeping 2s' 'sleep amount doubles'
is $rc 1 'failing command returns no success'
set +e; out=$(retry -r 1 -- sh -c 'echo -n .; false' 2>/dev/null); set -e
is "$out" '..' 'specified number of tries (1+retries)'
set +e; out=$(retry -r 0 -s 0 false 2>&1); rc=$?; set -e
is $rc 1 'failing command without retry returns no success'
set +e; out=$(retry -r 0 -s 0 true 2>&1); rc=$?; set -e
is $rc 0 'passing command without retry returns no error'
trap "rm -f 'run_count.txt'" EXIT
set +e; out=$(retry -r 2 -s 0 $dir/success_on_third.sh 2>&1); rc=$?; set -e
like "$out" 'Retrying up to 2 more' 'number of retries printed'
is $rc 0 'pass on last run is success'
set +e; out=$(retry -r-1 -s 0 $dir/success_on_third.sh 2>&1); rc=$?; set -e
like "$out" 'Retrying after sleeping' 'infinite retries without number of retries'
is $rc 0 'pass on last run with infinite retries is success'
07070100000010000081FD0000000000000000000000016788E86D000000F3000000000000000000000000000000000000003900000000retry-1737025645.819c129/test/fail-once-every-third-call#!/bin/bash
TMPDIR="${TMPDIR:-"/tmp"}"
tmp="${tmp:-"$TMPDIR/tmp.$(basename "$0")"}"
if [ -e "$tmp" ]; then
    attempts="$(cat "$tmp")"
fi
if [[ -z "$attempts" ]]; then
    attempts=0
fi
((attempts++))
echo "$attempts" > "$tmp"
((attempts%3))
07070100000011000081FD0000000000000000000000016788E86D00000292000000000000000000000000000000000000003200000000retry-1737025645.819c129/test/success_on_third.sh#!/bin/bash

# Set the path to the file that will store the run count in /var/run directory
count_file="run_count.txt"

# Initialize the count file if it doesn't exist
if [ ! -f "$count_file" ]; then
  echo "0" > "$count_file"
fi

# Read the current run count from the file
run_count=$(<"$count_file")

# Increment the run count
((run_count++))

# Write the updated run count back to the file
echo "$run_count" > "$count_file"

# Check if it's the third run and exit with an error if true
if [ "$((run_count % 3))" -gt 0 ]; then
  echo "Failing on the  run!"
  exit 1
fi

# Your script logic goes here
echo "Script is running successfully on run $run_count"
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!36 blocks
openSUSE Build Service is sponsored by