#!/bin/bash
# Improve error handling, option e is not picked because it's expected for functions
# to return non-0 statuses.
set -Eeuo pipefail
# Allow user input during commit
exec < /dev/tty
# Allow modifying aliases
shopt -s expand_aliases
templates_content='{}'
templates_names=()
unique_json_files=()
unique_filterlists_to_include=()
all_domains_variables_in_json_files='[]'
all_domains_variables_names='{}'
all_json_files_contents='{}'
variables_in_json_files='{}'
variables_in_included_filterlists='{}'
all_domain_variables_matches_in_filterlists='[]'
last_error=''
unstaged_files=''
testing=false
# When using Windows there is a problem with return character, therefore there is a need for extra --binary option. Look https://jqlang.github.io/jq/manual/
# In general running this script directly within windows is very slow, so use of WSL2 is recommended but in case of some tests performed in windows, those lines are still needed.
if [ $OSTYPE = 'msys' ] || [ $OSTYPE = 'cygwin' ]; then
alias jq='jq -b'
else
alias jq='command jq'
fi
# Mac grep doesn't have Perl regex, therefor it needs to be checked with another method
if [[ $OSTYPE == 'darwin'* ]]; then
alias grep='ggrep'
else
alias grep='command grep'
fi
# In case on WSL (Windows) it's faster to invoke git.exe directly from Windows (since the files are in the windows FS).
if [ -n "${WSL_DISTRO_NAME:-}" ]; then
alias git='git.exe'
else
alias git='command git'
fi
error_handler() {
local exit_code=$?
local line_number=$1
echo "Error: Script failed with exit code $exit_code at line $line_number"
if [ "${BASH_COMMAND:-}" = "return 1" ]; then
echo -e "Last error message:\n$last_error"
else
echo -e "\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
echo "THIS ERROR SHOULDN'T HAPPEN, PLEASE REPORT IT TO AFB TEAM OR KRIS"
echo -e "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n"
echo "Last executed command: ${BASH_COMMAND:-}"
fi
if [ "$testing" = true ] && [ "${BASH_COMMAND:-}" = "return 1" ]; then
exit 0
else
exit $exit_code
fi
}
# Set up trap to catch errors and invoke the error handler
trap 'error_handler $LINENO' ERR
get_unstaged_files() {
unstaged_files=$(git ls-files . --exclude-standard --others -m)
local git_exit_code=$?
if [ $git_exit_code -ne 0 ]; then
last_error="Wrong setting of git, be sure that you run git as the same user as you cloned repo"
return 1
fi
if [ -n "$unstaged_files" ]; then
read -p "There are changes not staged for commit. The script will check only the staged version. Do you want to continue? (y/n): " choice
case "$choice" in
y|Y ) echo "";;
n|N ) echo "Aborting."; exit 1;;
* ) echo "Invalid choice. Aborting."; exit 1;;
esac
fi
}
get_staged_files() {
local -n staged_files_nameref=$1
staged_files_nameref=$(git diff --name-only --cached)
}
check_if_jq_is_installed() {
if ! command -v jq &>/dev/null; then
last_error="ERROR: jq is not installed. Please install jq to continue."
return 1
fi
}
check_if_file_exists() {
local file_path="$1"
if ! [ -f "$file_path" ]; then
last_error="ERROR: File $file_path does not exist"
return 1
fi
}
check_if_unstaged_changes() {
local file_path=$1
local -n answer_nameref=$2
check_if_file_exists "$file_path"
local git_status=$(git status $file_path)
local lines_indicating_changes=$(grep -s "Changes not staged for commit" <<< $git_status || grep -s "Untracked files:" <<< $git_status || echo '')
if [ -n "$lines_indicating_changes" ]; then
answer_nameref=true
else
answer_nameref=false
fi
}
get_staged_version_of_a_file() {
local file_name="$1"
# Using name reference in order to not create subshells for each assignment and allow to use global variables
# and global error handling
local -n staged_file_content_nameref=$2
check_if_file_exists "$file_name"
local matched_unstaged_file=$(grep -x "$file_name" <<< "$unstaged_files" || echo '')
if [ -n "$matched_unstaged_file" ]; then
staged_file_content_nameref=$(git show ":$file_name" || echo '')
else
staged_file_content_nameref=$(cat "$file_name")
fi
if [ -z "$staged_file_content_nameref" ]; then
last_error="ERROR: File $file_name was requested by a template but it's not tracked neither staged."
return 1
fi
}
parse_template_data() {
local template="$1"
local -n file_data_nameref=$2
local staged_template
get_staged_version_of_a_file "$template" staged_template
# Extract lines starting with %domainsVariables exceptionrules: and process them with jq
local json_files_in_template=$(grep "^%domainsVariables exceptionrules:" <<< $staged_template | sed 's/^%domainsVariables exceptionrules://; s/%$//' | jq -Rs 'split("\n") | map(select(length > 0))' || echo '')
# Extract lines starting with %include exceptionrules: and process them with jq
local included_filterlists_files_in_template=$(grep "^%include exceptionrules:" <<< $staged_template | sed 's/^%include exceptionrules://; s/%$//' | jq -Rs 'split("\n") | map(select(length > 0))' || echo '')
if [ "$included_filterlists_files_in_template" = "[]" ]; then
last_error="ERROR: There is no list included in template $template_name"
return 1
fi
# Create a JSON object with the template name as the key and the extracted domainsVariables and include data as values
file_data_nameref=$(jq -n --arg template "$template" --argjson json_files_in_template "$json_files_in_template" --argjson included_filterlists_files_in_template "$included_filterlists_files_in_template" '
{
$template: {
"domainsVariables": $json_files_in_template,
"include": $included_filterlists_files_in_template
}
}')
}
update_templates_content() {
local file_template="$1"
# Merge the new template data into the existing templates_content JSON
templates_content=$(jq -n --argjson templates_content "$templates_content" --argjson file_template "$file_template" '$templates_content + $file_template')
}
update_unique_json_files() {
local template_name="$1"
local file_data="$2"
# Extract the list of domainsVariables files from the template data
local json_files_list=$(jq -r --arg template_name "$template_name" '.[$template_name].domainsVariables[]' <<< $file_data)
for json_file in $json_files_list; do
local matches_in_unique_json_files=$(grep -swF "$json_file" <<< ${unique_json_files[@]} || echo '')
if [ -z "$matches_in_unique_json_files" ]; then
unique_json_files+=("$json_file")
fi
done
}
update_unique_includes() {
local template_name="$1"
local file_data="$2"
# Extract the list of included files from the template data
local included_files_list=$(jq -r --arg file "$template_name" '.[$file].include[]' <<< $file_data)
for included_filterlist in $included_files_list; do
local matches_in_unique_filterlists=$(grep -swF "$included_filterlist" <<< ${unique_filterlists_to_include[@]} || echo '')
if [ -z "$matches_in_unique_filterlists" ]; then
unique_filterlists_to_include+=("$included_filterlist")
fi
done
}
check_if_valid_json() {
local json_file_path="$1"
if ! jq -e . >/dev/null 2>&1 <<< $(cat "$json_file_path"); then
last_error="ERROR: Invalid JSON content in $json_file_path"
return 1
fi
}
get_domains_variables_names_incl_duplicates() {
local json_file_content="$1"
local -n domains_variables_names_incl_duplicated_nameref=$2
# If jq would be used the duplicates would be automatically removed, therefore I used perl
domains_variables_names_incl_duplicated_nameref=$(perl -0777 -ne 'print "$1\n" while /"([^"]+?)"(?=[\s\r\n]*:)/g' <<< $json_file_content)
}
check_if_correct_domains_variables_json_structure() {
local json_file_content="$1"
local json_file_path="$2"
# Check if the JSON structure is valid and matches the expected format:
# { "variable1": ["domain1", "domain2" (...)], "variable2": ["domain1", "domain3" (...)], (...)}
if ! echo $json_file_content | jq -e '
type == "object" and
([keys[] as $k | .[$k] | type == "array" and all(.[]; type == "string")] | all)
' >/dev/null 2>&1;
then
last_error="ERROR: JSON structure is invalid in $json_file_path"
return 1
fi
}
check_if_duplicated_domains_variable_name_in_single_file() {
local json_file_path="$1"
local domains_variables_names="$2"
if [ "$(echo "$domains_variables_names" | sort | uniq -d)" ]; then
last_error="ERROR: Duplicate domains_variables_names found in $json_file_path"
return 1
fi
}
check_if_valid_domains_variable_name() {
local domains_variable_name="$1"
if ! [[ "$domains_variable_name" =~ ^[[:alnum:]_]+$ ]]; then
last_error="ERROR: Invalid domains variable name: $domains_variable_name, only alphanumeric characters and underscores are allowed"
return 1
fi
}
check_if_duplicated_domains() {
local json_file_path="$1"
local key="$2"
local value="$3"
# Value of domainsVariable is an array of strings representing domains,
# therefore the error message mentions domains.
if [ -n "$(echo "$value" | sort | uniq -di)" ]; then
last_error="ERROR: There are duplicated domains in $key in file $json_file_path:\n"
last_error+="$(echo "$value" | sort | uniq -di)"
return 1
fi
}
check_if_correct_domain() {
local json_file_path="$1"
local domains_variable_name="$2"
local domains="$3"
# Preselect candidates for invalid domains, then check them
local candidates=$(grep -vP "^(([A-Za-z0-9][A-Za-z0-9-]{0,61})?[A-Za-z0-9]\.)+([A-Za-z]{2,63}|\*|xn--[a-zA-Z0-9-]{1,59})$" <<< $domains || echo '')
if [ -n "$candidates" ]; then
last_error="ERROR: Invalid domain in $domains_variable_name: $candidates in file $json_file_path"
return 1
fi
}
check_if_correct_domains_variables() {
local json_file_path="$1"
local domains_variables_names="$2"
local json_file_content="$3"
check_if_duplicated_domains_variable_name_in_single_file "$json_file_path" "$domains_variables_names"
for domains_variable_name in $domains_variables_names; do
check_if_valid_domains_variable_name "$domains_variable_name"
# Extract the value associated with the domains variable name from the JSON file
local domains=$(jq -r --arg key "$domains_variable_name" '.[$key][]' <<< $json_file_content)
check_if_duplicated_domains "$json_file_path" "$domains_variable_name" "$domains"
check_if_correct_domain "$json_file_path" "$domains_variable_name" "$domains"
done
}
update_domains_variables_data() {
local domains_variables_names="$1"
local json_file_path="$2"
local json_file_content="$3"
# Merge the new domains variables into the existing all_domains_variables_in_json_files array
all_domains_variables_in_json_files=$(jq -n --argjson all_domains_variables_in_json_files "$all_domains_variables_in_json_files" --argjson domains_variables_names "$(echo "$domains_variables_names" | jq -Rs 'split("\n") | map(select(length > 0))')" '$all_domains_variables_in_json_files + $domains_variables_names | unique')
# Adding all the json files content to the variable was causing "Too big variable" error
# Therefore, the content is saved to a temporary file and then loaded back to the variable
all_json_files_temp_file=$(mktemp)
echo "$all_json_files_contents" > "$all_json_files_temp_file"
json_file_content_temp=$(mktemp)
echo "$json_file_content" > "$json_file_content_temp"
all_json_files_contents=$(jq --arg json_file_path "$json_file_path" --slurpfile json_file_content "$json_file_content_temp" '.[$json_file_path] = $json_file_content[0]' "$all_json_files_temp_file")
rm "$json_file_content_temp"
rm "$all_json_files_temp_file"
# Update the variables_in_json_files object with the keys from the JSON file
variables_in_json_files=$(echo "$variables_in_json_files" | jq --arg key "$json_file_path" --argjson value "$(echo "$all_json_files_contents" | jq 'to_entries | map({key: .key, value: (.value | keys)}) | from_entries' | jq --arg key "$json_file_path" '.[$key]')" '. * {($key): $value}')
}
check_if_duplicated_domains_variable_name_between_files() {
local json_file_path="$1"
local domains_variables_names="$2"
for domains_variable_name in $domains_variables_names; do
# Check if the domains variable name exists in the all_domains_variables_in_json_files array
if jq -e --arg name "$domains_variable_name" 'index($name) != null' <<< $all_domains_variables_in_json_files >/dev/null 2>&1; then
# If a duplicate is found, identify the file containing the duplicate and report an error
local file_with_duplicate=$(jq -r --arg name "$domains_variable_name" '
to_entries | map(select(.value | has($name))) | .[0].key
' <<< $all_json_files_contents)
last_error="ERROR: Duplicate domains variable found in $json_file_path and $file_with_duplicate file: $domains_variable_name"
return 1
fi
done
}
find_domain_variables_syntax_in_filterlist() {
local filterlist_content="$1"
local filterlist_path="$2"
local -n all_lines_with_domain_variables_in_filterlist_nameref=$3
# Find lines containing domain variables in the filterlist
# The regex to find them is simpler than in filterlist delivery to also catch domains variables in the wrong place
# without starting with a complex regex. The full regex is in one of the next steps
all_lines_with_domain_variables_in_filterlist_nameref=$(grep -P '%<\{.*\}>%' <<< $filterlist_content || echo '')
}
check_for_similar_to_domain_variable() {
local filterlist_content="$1"
local filterlist_path="$2"
# Precheck to quickly gather only the potentiall candidates for the full check
local weak_candidates=$(grep -P "[%{}<>].\w+.[%{}<>]" <<< $filterlist_content || echo '')
local candidates=$(grep -P "[%{}<>].?[%{}<>].*[%{}<>].?[%{}<>]" <<< $weak_candidates || echo '')
local strong_candidates=$(grep -oP "([^%{}<>]|^)[%{}<>]+.?[%{}<>]+.*[%{}<>]+.?[%{}<>]+([^%{}<>]|$)" <<< $candidates || echo '')
if [ -n "$strong_candidates" ]; then
local lines_with_similar_to_domain_variable=$(grep -vP "([|,=]|^)%<\{\w+\}>%([,|#]|$)" <<< $candidates || echo '')
if [ -n "$lines_with_similar_to_domain_variable" ]; then
last_error="ERROR: Found a line in $filterlist_path that is similar to a domain variable, but it's not a domain variable:\n\n"
last_error+="$lines_with_similar_to_domain_variable"
return 1
fi
fi
}
process_filters() {
local all_lines_with_domain_variables_in_filterlist="$1"
local -n domains_variables_collected_from_filterlist_nameref="$2"
domains_variables_collected_from_filterlist_nameref='[]'
for filter in $all_lines_with_domain_variables_in_filterlist; do
# Extract the domain variable from the filter
local domains_variable_match=$(grep -oP '(?<=%<\{).*?(?=\}>%)' <<< $filter)
if [ "$(echo "$domains_variable_match" | wc -l)" -gt 1 ]; then
last_error="ERROR: More than 2 domain variables found in filter: $filter"
return 1
fi
# Ensure the domain variable is correctly formatted in the filter
local true_matches
true_matches=$(grep -P '(%<{(\w+)}>%(?:,~?[a-zA-Z0-9*.~-]+)*#[?@$]?#)|([,$]domain=(?:[a-zA-Z0-9*.~-]+\|)*%<{(\w+)}>%)' <<< $filter)
if [ -z "$true_matches" ]; then
last_error="ERROR: Domain variable added in a wrong way in filter: $filter"
return 1
fi
domains_variables_collected_from_filterlist_nameref=$(jq --arg domains_variable_match "$domains_variable_match" '. + [$domains_variable_match]' <<< $domains_variables_collected_from_filterlist_nameref)
done
}
update_matches_and_variables() {
local domains_variables_collected_from_filterlist="$1"
local file_path="$2"
# Update the list of all domain variable matches in filterlists
all_domain_variables_matches_in_filterlists=$(jq -n --argjson all_domain_variables_matches_in_filterlists "$all_domain_variables_matches_in_filterlists" --argjson matches "$domains_variables_collected_from_filterlist" '$all_domain_variables_matches_in_filterlists + $matches | unique')
# Update the variables_in_included_filterlists object with the matches from the current filterlist
variables_in_included_filterlists=$(jq --arg key "$file_path" --argjson value "$domains_variables_collected_from_filterlist" '.[$key] = $value' <<< $variables_in_included_filterlists)
}
extract_domains_variables_in_included_filterlists() {
local template_name="$1"
local -n domains_variables_in_included_filterlists_nameref=$2
# Extract the list of included filterlists from the template
local included_filterlists=$(jq -r --arg template_name "$template_name" '.[$template_name].include[]' <<< "$templates_content")
domains_variables_in_included_filterlists_nameref=()
for included_filterlist in $included_filterlists; do
# Extract the domain variables from each included filterlist
local domains_variables=$(jq -r --arg included_filterlist "$included_filterlist" '.[$included_filterlist][]' <<< "$variables_in_included_filterlists")
for domain_variable in $domains_variables; do
domains_variables_in_included_filterlists_nameref+=("$domain_variable")
done
done
}
extract_domains_variables_in_included_json_files() {
local template_name="$1"
local -n domains_variables_in_included_json_files_nameref=$2
# Extract the list of included JSON files from the template
local included_json_files=$(jq -r --arg template_name "$template_name" '.[$template_name].domainsVariables[]' <<< $templates_content)
domains_variables_in_included_json_files_nameref=()
for included_json_file in $included_json_files; do
# Extract the domain variables from each included JSON file
local domains_variables=$(jq -r --arg key "$included_json_file" '.[$key][]' <<< $variables_in_json_files)
for domain_variable in $domains_variables; do
domains_variables_in_included_json_files_nameref+=("$domain_variable")
done
done
}
check_domain_variables_in_filterlists() {
local template_name="$1"
local domains_variables_in_included_filterlists=()
local domains_variables_in_included_json_files=()
# When for example $2 was empty, then the array had one element with empty string
if [ -n "$2" ]; then
domains_variables_in_included_filterlists=($2)
fi
if [ -n "$3" ]; then
domains_variables_in_included_json_files=($3)
fi
# Extract the list of included filterlists and JSON files from the template
local included_filterlists=$(jq -r --arg template_name "$template_name" '.[$template_name].include[]' <<< $templates_content)
local included_json_files=$(jq -r --arg template_name "$template_name" '.[$template_name].domainsVariables[]' <<< $templates_content)
for domain_variable_in_filterlist in ${domains_variables_in_included_filterlists[@]}; do
local found=false
for domain_variable_in_json_file in ${domains_variables_in_included_json_files[@]}; do
if [ "$domain_variable_in_filterlist" = "$domain_variable_in_json_file" ]; then
found=true
break
fi
done
if ! $found; then
last_error="Error: One of the filterlists:\n\n"
last_error+="$included_filterlists\n\n"
last_error+="included in the template $template_name contain a domain variable $domain_variable_in_filterlist "
last_error+="which wasn't found in any of the domains variables files included in that template:\n\n"
last_error+="$included_json_files"
return 1
fi
done
}
check_if_domains_variables_are_identical_in_lists_and_jsons() {
if [ "$all_domains_variables_in_json_files" != "$all_domain_variables_matches_in_filterlists" ]; then
last_error="Error: the domain variables in domain-variables file and the filter list are not the same\n"
last_error+="Extra variables in domain-variables files:\n"
last_error+="$(jq -n --argjson all_domains_variables_in_json_files "$all_domains_variables_in_json_files" --argjson all_domain_variables_matches_in_filterlists "$all_domain_variables_matches_in_filterlists" '$all_domains_variables_in_json_files - $all_domain_variables_matches_in_filterlists')\n"
last_error+="Extra variables in filter lists:\n"
last_error+=$(jq -n --argjson all_domains_variables_in_json_files "$all_domains_variables_in_json_files" --argjson all_domain_variables_matches_in_filterlists "$all_domain_variables_matches_in_filterlists" '$all_domain_variables_matches_in_filterlists - $all_domains_variables_in_json_files')
return 1
fi
}
main() {
get_unstaged_files
check_if_jq_is_installed
for template_name in *.txt; do
templates_names+=("$template_name")
# To avoid creating a subshell, the variable is passed as a reference to parse_template_data function
# That helps with the error handling and allows to use global variables
local file_data
# Parse data from the template
parse_template_data "$template_name" file_data
# Update the templates_content JSON with the data from the file
update_templates_content "$file_data"
update_unique_json_files "$template_name" "$file_data"
update_unique_includes "$template_name" "$file_data"
done
for domains_variables_path in ${unique_json_files[@]}; do
local staged_domains_variables_file
get_staged_version_of_a_file "$domains_variables_path" staged_domains_variables_file
check_if_correct_domains_variables_json_structure "$staged_domains_variables_file" "$domains_variables_path"
local domains_variables_names_incl_duplicates
get_domains_variables_names_incl_duplicates "$staged_domains_variables_file" domains_variables_names_incl_duplicates
check_if_correct_domains_variables "$domains_variables_path" "$domains_variables_names_incl_duplicates" "$staged_domains_variables_file"
check_if_duplicated_domains_variable_name_between_files "$domains_variables_path" "$domains_variables_names_incl_duplicates"
update_domains_variables_data "$domains_variables_names_incl_duplicates" "$domains_variables_path" "$staged_domains_variables_file"
done
for filterlist_path in ${unique_filterlists_to_include[@]}; do
local filterlist_content
get_staged_version_of_a_file "$filterlist_path" filterlist_content
check_for_similar_to_domain_variable "$filterlist_content" "$filterlist_path"
local all_lines_with_domain_variables_in_filterlist
find_domain_variables_syntax_in_filterlist "$filterlist_content" "$filterlist_path" all_lines_with_domain_variables_in_filterlist
if [ -z "$all_lines_with_domain_variables_in_filterlist" ]; then
# In case of lack of matches, the value of all_lines_with_domain_variables_in_filterlist should have just
# a message to show.
local domains_variables_collected_from_filterlist='[]'
else
local domains_variables_collected_from_filterlist
process_filters "$all_lines_with_domain_variables_in_filterlist" domains_variables_collected_from_filterlist
fi
update_matches_and_variables "$domains_variables_collected_from_filterlist" "$filterlist_path"
done
local domains_variables_in_included_filterlists=()
for template_name in ${templates_names[@]}; do
extract_domains_variables_in_included_filterlists "$template_name" domains_variables_in_included_filterlists
local domains_variables_in_included_json_files
extract_domains_variables_in_included_json_files "$template_name" domains_variables_in_included_json_files
check_domain_variables_in_filterlists "$template_name" "$(echo ${domains_variables_in_included_filterlists[@]})" "$(echo ${domains_variables_in_included_json_files[@]})"
done
check_if_domains_variables_are_identical_in_lists_and_jsons
}
check_unit_tests() {
local exit_status=0
bash ./pre-commit-src/tests/pre-commit-tests.sh '--no-verbose' || exit_status=1
function_exit_code=$?
if [ $exit_status -ne 1 ]; then
exit_status=$function_exit_code
fi
if [ $exit_status -ne 0 ]; then
last_error="Unit tests failed with exit code $exit_status"
last_error+="\nPlease fix the issues before continuing"
last_error+="To check the details run 'pre-commit-src/tests/pre-commit-tests.sh'"
return $exit_status
else
last_error="Unit tests passed successfully"
fi
}
check_pre_commit_files() {
local staged_files
get_staged_files staged_files
local pre_commit_path='pre-commit-src/pre-commit'
check_if_file_exists "$pre_commit_path"
local matched_pre_commit_in_unstaged=$(grep -x "$pre_commit_path" <<< "$unstaged_files" || echo '')
if [ -n "$matched_pre_commit_in_unstaged" ]; then
last_error="Unstaged changes detected in pre-commit file. Stage pre-commit changes before continuing."
return 1
fi
local pre_commit_script_path='pre-commit-src/pre-commit-script.sh'
check_if_file_exists "$pre_commit_script_path"
local matched_pre_commit_script_in_unstaged=$(grep -x "$pre_commit_script_path" <<< "$unstaged_files" || echo '')
if [ -n "$matched_pre_commit_script_in_unstaged" ]; then
last_error="Unstaged changes detected in pre-commit-script.sh file. Stage pre-commit-script changes before continuing."
return 1
fi
pre_commit_tests_path='pre-commit-src/tests/pre-commit-tests.sh'
check_if_file_exists "$pre_commit_tests_path"
local matched_pre_commit_tests_in_unstaged=$(grep -x "$pre_commit_tests_path" <<< "$unstaged_files" || echo '')
if [ -n "$matched_pre_commit_tests_in_unstaged" ]; then
last_error="Unstaged changes detected in pre-commit-tests file. Stage pre-commit tests changes before continuing."
return 1
fi
# Only if something changed in pre commit or pre commit tests the unit tests should be run
if [ -z "$matched_pre_commit_in_unstaged$matched_pre_commit_script_in_unstaged$matched_pre_commit_tests_in_unstaged" ]; then
check_unit_tests
fi
}
# For testing purposes only if the script has no arguments or the argument is main the process should run
# thanks to that the script can be tested without running the main function
if [ -z "${1:-}" ]; then
echo 'Running pre-commit checks...'
main
check_pre_commit_files
echo "Pre-commit checks passed successfully. Double check if there were no error messages above this message before pushing"
unalias jq
unalias grep
unalias git
exit 0
elif [ "$1" = "--load-only" ]; then
testing=true
echo "Script loaded successfully"
else
echo Wrong option provided "$@"
unalias jq
unalias grep
unalias git
exit 1
fi