From cbc1d68ab46305e321a655b9a86b971921f73b5f Mon Sep 17 00:00:00 2001 From: ge Date: Sat, 14 May 2022 17:49:46 +0300 Subject: [PATCH] feat: Rename script.sh to source.sh --- src/lib/source.sh | 114 +++++++++++++++++++++++++++++++++++++++ tests/source_script.bats | 20 +++---- 2 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 src/lib/source.sh diff --git a/src/lib/source.sh b/src/lib/source.sh new file mode 100644 index 0000000..d1c39ea --- /dev/null +++ b/src/lib/source.sh @@ -0,0 +1,114 @@ +#! /usr/bin/env bash + +# script.sh - utilitary functions. +# Copyright (c) 2022 ge +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +validate_sources() { + # Check sources array. + # + # Usage: validate_sources ARRAY + + # Allowed URI schemes: file, mysql postgres, sqlite + # No required schemes. + + local array=("$@") + local scheme= + + for uri in "${array[@]}"; do + scheme="${uri%%:*}" + case "$scheme" in + file|mysql|postgres|sqlite) : ;; # do nothing, this is OK + *) echo "Error: Unsupported URI scheme: $scheme" >&2; exit 1;; + esac + done +} + +validate_targets() { + # Check targets array and set local_target variable. + # + # Usage: validate_targets ARRAY + + # Allowed URI schemes: file, ftp, sftp, rsync, s3, swift, sj, dav, davs + # Required schemes (one or more times): file + + local array=("$@") + local scheme= + local file_targets=() + + for uri in "${array[@]}"; do + scheme="${uri%%:*}" + case "$scheme" in + file|ftp|sftp|rsync|s3|swift|sj|dav|davs) + if [[ "$scheme" == file ]]; then + file_targets+=("$uri") + fi + ;; + *) echo "Error: Unsupported URI scheme: $scheme" >&2; exit 1;; + esac + done + + if [ "${#file_targets[@]}" -eq 0 ]; then + echo "Error: 'file' scheme is not set in targets." \ + "You must provide one or more targets with 'file' scheme." >&2 + exit 1 + else + # Set local_target. This variable contains path to save local backups. + # Files to additional targets will be coped from this directory. + local_target="${file_targets[0]}" + fi +} + +source_script() { + # Safely as possible source backup script. + # + # Usage: source_script SCRIPT + + local script="$1" + + if ! test -f "$script"; then + echo "Error: No such file: $script" >&2; exit 1 + fi + + # Dry run script, check syntax. See set(1p) + if ! bash -n "$script"; then + echo Error: Please check your syntax >&2; exit 1 + fi + + # Source script + . "$@" + + # Check required variables + if [[ "$sources" ]]; then + validate_sources "${sources[@]}" + else + echo Error: sources array is not set >&2; exit 1 + fi + + if [[ "$targets" ]]; then + validate_targets "${targets[@]}" + else + echo Error: targets array is not set >&2; exit 1 + fi +} + +is_function_set() { + # Test function is set or not. Return exit code. + # Useful with 'if' statement. + # + # Usage: is_function_set FUNCTION + + declare -F -- "$1" > /dev/null +} diff --git a/tests/source_script.bats b/tests/source_script.bats index ae2ced2..0ff95de 100644 --- a/tests/source_script.bats +++ b/tests/source_script.bats @@ -1,6 +1,6 @@ #! /usr/bin/env bats -# source_script() from lib/script.sh tests. +# source_script() from lib/source.sh tests. # See: https://bats-core.readthedocs.io/en/latest/index.html setup() { @@ -16,55 +16,55 @@ setup() { # ------------------------------ # @test "Bad script syntax" { - . script.sh + . source.sh run source_script $DIR/files/bad_syntax.plan assert_output --partial 'Error: Please check your syntax' } @test "Empty script" { - . script.sh + . source.sh run source_script $DIR/files/empty_script.plan assert_output --partial 'Error: sources array is not set' } @test "Empty sources array" { - . script.sh + . source.sh run source_script $DIR/files/empty_sources.plan assert_output --partial 'Error: sources array is not set' } @test "Empty targets array" { - . script.sh + . source.sh run source_script $DIR/files/empty_targets.plan assert_output --partial 'Error: targets array is not set' } @test "No targets with 'file' URI scheme" { - . script.sh + . source.sh run source_script $DIR/files/no_file_target.plan assert_output --partial "Error: 'file' scheme is not set in targets. You must provide one or more targets with 'file' scheme." } @test "Unsuported source scheme" { - . script.sh + . source.sh run source_script $DIR/files/unsupported_source_scheme.plan assert_output --partial 'Error: Unsupported URI scheme: mongo' } @test "Unsuported target scheme" { - . script.sh + . source.sh run source_script $DIR/files/unsupported_target_scheme.plan assert_output --partial 'Error: Unsupported URI scheme: scp' } @test "Set local target" { - . script.sh + . source.sh source_script $DIR/files/basic.plan [ "$local_target" == 'file:/var/backup' ] } @test "Set local target from multiple 'file' targets" { - . script.sh + . source.sh source_script $DIR/files/multiple_file_targets.plan [ "$local_target" == 'file:///home/backups' ] }