Skip to content

Commit

Permalink
General editing has been done for readability.
Browse files Browse the repository at this point in the history
  • Loading branch information
KaganCanSit committed Jun 20, 2024
1 parent 4cc61f3 commit e0136fe
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 103 deletions.
146 changes: 76 additions & 70 deletions linkChecker.sh
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
#!/bin/bash

# Outside parameter
# ------------------------------------------ Parameters -------------------------------------------------
SCAN_DIRECTORY="$1"
ERROR_ONLY=${2:-false}
LINKS_WITH_FILE=${3:-false}
THREAD_COUNT=${4:-10}

# Define
# There may be links you don't want checked during the scan. For example, you typed "hhtp://remote_repository_address.git"
# for a code sample or a site where login is required. You can write these links to the "disabled_control_links.txt" file that
# you will define in the same directory as the script.
DISABLED_CONTROL_LINKS_FILE="disabled_control_links.txt"

# --------------------------------------- Script Requirements Check ----------------------------------------------
if [ "$#" -eq 0 ] || [ "$1" == "--help" ] || [ "$1" == "-h" ]; then
# ------------------------------------------- Functions -------------------------------------------------
function display_help() {
cat <<EOF
Usage: $0 <directory> <error_only> <links_with_file> <thread_count>
Parameters:
Expand All @@ -24,59 +20,8 @@ Parameters:
Example:
$0 /path/to/directory true true 20
EOF
exit 1
fi

# Check if SCAN_DIRECTORY is provided and exists
if [ -z "$SCAN_DIRECTORY" ] || [ ! -d "$SCAN_DIRECTORY" ]; then
echo "Error: Please provide a valid directory to scan."
exit 1
fi

# Check if ERROR_ONLY and WRITE_TO_FILE are true or false
for param in "$ERROR_ONLY" "$LINKS_WITH_FILE"; do
if [[ "$param" != "true" && "$param" != "false" ]]; then
echo "Error: Parameters must be either true or false."
exit 1
fi
done

# Check if THREAD_COUNT is provided and is a positive integer
if ! [[ "$THREAD_COUNT" =~ ^[1-9][0-9]*$ ]]; then
echo "Error: THREAD_COUNT must be a positive integer."
exit 1
fi

# Check if required packages are installed
for package_name in curl parallel; do
if ! command -v "$package_name" &>/dev/null; then
echo "'$package_name' is not installed. Do you want to install it now? (yes/no)"
read -r response
if [[ "$response" =~ ^[Yy][Ee][Ss]|[Yy]$ ]]; then
# Operation system check
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
if command -v apt-get &>/dev/null; then
sudo apt-get install "$package_name"
elif command -v yum &>/dev/null; then
sudo yum install "$package_name"
elif command -v pacman &>/dev/null; then
sudo pacman -S "$package_name"
else
echo "Unsupported package manager. Please install $package_name manually."
exit 1
fi
else
echo "Unsupported operating system. Please install $package_name manually."
exit 1
fi
else
echo "$package_name is required for this script to run. Please install $package_name and try again."
exit 1
fi
fi
done
}

# ------------------------------------------------ Functions -------------------------------------------------
function log() {
local level="$1"
local message="$2"
Expand Down Expand Up @@ -109,6 +54,35 @@ function log() {
fi
}

# Install required packages if not present
check_and_install_package() {
local package_name="$1"
if ! command -v "$package_name" &>/dev/null; then
log "INFO" "'$package_name' is not installed. Do you want to install it now? (yes/no)"
read -r response
if [[ "$response" =~ ^[Yy][Ee][Ss]|[Yy]$ ]]; then
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
if command -v apt-get &>/dev/null; then
sudo apt-get install "$package_name"
elif command -v yum &>/dev/null; then
sudo yum install "$package_name"
elif command -v pacman &>/dev/null; then
sudo pacman -S "$package_name"
else
log "ERROR" "Unsupported package manager. Please install $package_name manually."
exit 1
fi
else
log "ERROR" "Unsupported operating system. Please install $package_name manually."
exit 1
fi
else
log "ERROR" "Exiting. $package_name is required for this script to run. Please install $package_name and try again."
exit 1
fi
fi
}

# Function that does not check whether the connection contains content other than "http", "https", "www" and domain name extensions (.com, .org, etc.)
function check_url_content() {
local url=$1
Expand Down Expand Up @@ -171,8 +145,7 @@ function find_links() {
printf "%s\n" "${found_links[@]}" | sort -u
}

# Function to check the status of a link
function check_link() {
function check_link_status() {
local link="$1"
local response
local http_code
Expand Down Expand Up @@ -203,7 +176,6 @@ function check_link() {
return 0
}

# Function to handle common curl errors
function handle_curl_error() {
local error_code="$1"
local link="$2"
Expand All @@ -223,7 +195,6 @@ function handle_curl_error() {
log "$log_level" "$log_message - $link" "${files[@]}"
}

# Function to handle HTTP status codes
function handle_http_code() {
local http_code="$1"
local link="$2"
Expand Down Expand Up @@ -283,15 +254,51 @@ function handle_http_code() {
# Export functions for parallel execution
export -f log
export -f check_url_content
export -f check_link
export -f check_link_status
export -f handle_curl_error
export -f handle_http_code

# ------------------------------------------------ Main Execution -------------------------------------------------
# ------------------------------- Parameter and Environment Checks --------------------------------------
# Check directorys parameter
if [ "$#" -lt 1 ]; then
log "ERROR" "Missing scan required parameters."
exit 1
fi

# Check if --help or -h is provided
if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then
display_help
exit 0
fi

# Check if SCAN_DIRECTORY is provided and exists
if [ -z "$SCAN_DIRECTORY" ] || [ ! -d "$SCAN_DIRECTORY" ]; then
log "ERROR" "Please provide a valid directory to scan."
exit 1
fi

# Check if ERROR_ONLY and WRITE_TO_FILE are true or false
for param in "$ERROR_ONLY" "$LINKS_WITH_FILE"; do
if [[ "$param" != "true" && "$param" != "false" ]]; then
log "ERROR" "Parameters must be either true or false."
exit 1
fi
done

# Check if THREAD_COUNT is provided and is a positive integer
if ! [[ "$THREAD_COUNT" =~ ^[1-9][0-9]*$ ]]; then
log "ERROR" "THREAD_COUNT must be a positive integer."
exit 1
fi

echo "OK! Let's do this. Link Checker is running..."
echo "Selected parameters: Directory: $SCAN_DIRECTORY, Error Only: $ERROR_ONLY, Links with File: $LINKS_WITH_FILE, Thread Count: $THREAD_COUNT"
# Check for required packages
for package in curl parallel; do
check_and_install_package "$package"
done

# ------------------------------------------------ Main -------------------------------------------------
log "INFO" "OK! Let's do this. Link Checker is running..."
log "INFO" "Selected parameters: Directory: $SCAN_DIRECTORY, Error Only: $ERROR_ONLY, Links with File: $LINKS_WITH_FILE, Thread Count: $THREAD_COUNT"
links_and_files=$(find_links "$SCAN_DIRECTORY")
if [[ -z "$links_and_files" ]]; then
echo "No links found to check."
Expand All @@ -316,11 +323,10 @@ done <<<"$links_and_files"
# Check links in parallel
for link in "${!link_files_map[@]}"; do
files=("${link_files_map["$link"]}")
check_link "$link" "${files[@]}" &
check_link_status "$link" "${files[@]}" &
if (($(jobs -r -p | wc -l) >= THREAD_COUNT)); then
wait -n
fi
done
wait

echo "Link Checker has finished. Have a nice day!"
log "INFO" "Link Checker has finished. Have a nice day!"
59 changes: 26 additions & 33 deletions tests/linkchecker.bats
Original file line number Diff line number Diff line change
Expand Up @@ -13,77 +13,72 @@ function check_output_contains() {
[[ "${output}" == *"$expected"* ]]
}

# Test if the script runs without errors
@test "Check if script runs without errors" {
@test "Test script with --help/-h flag and returns status 0" {
run bash linkChecker.sh --help
[ "$status" -eq 1 ]
[ "$status" -eq 0 ]

run bash linkChecker.sh -h
[ "$status" -eq 0 ]
}

# Test when no parameters are provided
@test "Check script with no parameters" {
run bash linkChecker.sh false false
@test "Test if no parameters returns status 1 with correct error message" {
run bash linkChecker.sh
[ "$status" -eq 1 ]
# Check return message
check_output_contains "Error: Please provide a valid directory to scan."
check_output_contains "Missing scan required parameters."
}

# Test with invalid first parameter (not a directory)
@test "Check script with invalid first parameter" {
@test "Test if providing a non-directory returns status 1 with correct error message" {
run bash linkChecker.sh "$TEST_DIRECTORY/test_links.txt"
[ "$status" -eq 1 ]
# Check return message
[[ "${output}" == *"Error: Please provide a valid directory to scan."* ]]
[[ "${output}" == *"Please provide a valid directory to scan."* ]]
}

# Test error_only parameter with invalid value
@test "Check error_only parameter with invalid value" {
@test "Test error_only parameter" {
# Invalid value
run bash linkChecker.sh "$TEST_DIRECTORY" test
[ "$status" -eq 1 ]
# Check return message
[[ "${output}" == *"Error: Parameters must be either true or false."* ]]
[[ "${output}" == *"Parameters must be either true or false."* ]]

# Valid values
run bash linkChecker.sh "$TEST_DIRECTORY" true
[ "$status" -eq 0 ]

run bash linkChecker.sh "$TEST_DIRECTORY" false
[ "$status" -eq 0 ]
}

# Test links_with_file parameter with invalid value
@test "Check links_with_file parameter with invalid value" {
@test "Test links_with_file parameter" {
# Invalid value
run bash linkChecker.sh "$TEST_DIRECTORY" true test
[ "$status" -eq 1 ]
# Check return message
[[ "${output}" == *"Error: Parameters must be either true or false."* ]]
[[ "${output}" == *"Parameters must be either true or false."* ]]

# Valid values
run bash linkChecker.sh "$TEST_DIRECTORY" true true
[ "$status" -eq 0 ]

run bash linkChecker.sh "$TEST_DIRECTORY" false false
[ "$status" -eq 0 ]
}

# Test thread_count parameter with invalid value
@test "Check thread_count parameter with invalid value" {
@test "Test thread_count parameter" {
# Invalid value
run bash linkChecker.sh "$TEST_DIRECTORY" true false aa
[ "$status" -eq 1 ]
# Check return message
[[ "${output}" == *"Error: THREAD_COUNT must be a positive integer."* ]]
[[ "${output}" == *"THREAD_COUNT must be a positive integer."* ]]

# Valid values
run bash linkChecker.sh "$TEST_DIRECTORY" false false 12
[ "$status" -eq 0 ]
}

# Test the error_only flag
@test "Check error_only flag" {
@test "Test error_only=true, no INFO and WARN messages are logged" {
run bash linkChecker.sh "$TEST_DIRECTORY" true
[ "$status" -eq 0 ]
# Only errors and warnings should be present in the output
[[ "${output}" != *"[INFO]"* ]] && [[ "${output}" != *"[LINK OK]"* ]]
[[ "${output}" != *"[INFO]"* ]] && [[ "${output}" != *"[LINK OK]"* ]] && [[ "${output}" != *"[WARN]"* ]]
}

# Test link checking functionality
@test "Check link checking functionality" {
@test "Test link checking functionality" {
run bash linkChecker.sh "$TEST_DIRECTORY"
[ "$status" -eq 0 ]
# Check if the output contains expected URL status
Expand Down Expand Up @@ -124,10 +119,8 @@ function check_output_contains() {
check_output_contains "[LINK NOT FOUND] - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Glabol_Objects/JSON/pars"
}

# Test when there are no links to check in a directory
@test "Check when no links to check in directory" {
@test "Test when no links are found in the directory" {
run bash linkChecker.sh "$ONLY_EXTENSIONS_DIRECTORY" false false
[ "$status" -eq 0 ]
# Check if the output contains expected message
[[ "${output}" == *"No links found to check."* ]]
}

0 comments on commit e0136fe

Please sign in to comment.