diff --git a/src/github.sh b/src/github.sh index 6a1692d..c13c5fe 100755 --- a/src/github.sh +++ b/src/github.sh @@ -8,50 +8,48 @@ github::get_pr_number() { github::get_commit_diff() { local -r pr_number="$1" - local -r files_to_ignore="${2}" + local -r files_to_ignore="$2" + local -r api_url="$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/pulls/$pr_number" - if [ -z "$files_to_ignore" ]; then - local -r body=$(curl -sSL -H "Authorization: token $GITHUB_TOKEN" -H "$GITHUB_API_HEADER" "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/pulls/$pr_number") - - echo "$body" + if [[ -z "$files_to_ignore" ]]; then + curl -sSL -H "Authorization: token $GITHUB_TOKEN" -H "$GITHUB_API_HEADER" "$api_url" else - local -r body=$(curl -sSL -H "Authorization: token $GITHUB_TOKEN" -H "$GITHUB_API_HEADER" "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/pulls/$pr_number/files?per_page=100") + local body + body=$(curl -sSL -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3+json" "$api_url/files?per_page=100") local diffs="" + while read -r file; do + local filename status + filename=$(jq -r '.filename' <<< "$file") + status=$(jq -r '.status' <<< "$file") - for file in $(echo "$body" | jq -r '.[] | @base64'); do - _jq() { - echo ${file} | base64 -d | jq -r ${1} - } - - filename=$(_jq '.filename') - status=$(_jq '.status') - ignore=false - - if [ "$status" == "removed" ]; then - continue - fi - - for pattern in $files_to_ignore; do - if [[ $filename == $pattern ]]; then - ignore=true - break - fi - done + [[ "$status" == "removed" ]] && continue - if [ "$ignore" = false ]; then - diffs+=$(_jq '.patch') + if ! github::should_ignore_file "$filename" "$files_to_ignore"; then + diffs+=$(jq -r '.patch' <<< "$file") diffs+=$'\n\n' fi - done + done < <(jq -c '.[]' <<< "$body") echo "$diffs" fi } +github::should_ignore_file() { + local -r filename="$1" + local -r files_to_ignore="$2" + + for pattern in $files_to_ignore; do + [[ "$filename" == $pattern ]] && return 0 + done + + return 1 +} + github::comment() { local -r comment="$1" local -r pr_number="$2" + local -r api_url="$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/issues/$pr_number/comments" curl -sSL \ -H "Authorization: token $GITHUB_TOKEN" \ @@ -59,5 +57,5 @@ github::comment() { -X POST \ -H "Content-Type: application/json" \ -d "$(jq -n --arg comment "$comment" '{body: $comment}')" \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/issues/$pr_number/comments" + "$api_url" } \ No newline at end of file diff --git a/src/main.sh b/src/main.sh index 2668c00..1480563 100755 --- a/src/main.sh +++ b/src/main.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash -trap "exit 1" TERM +set -euo pipefail + +trap 'exit 1' TERM export TOP_PID=$$ source "$HOME_DIR/src/utils.sh" @@ -12,7 +14,8 @@ source "$HOME_DIR/src/gpt.sh" ##? Usage: ##? main.sh --github_token= --open_ai_api_key= --gpt_model_name= --github_api_url= --files_to_ignore= main() { - eval "$(docpars -h "$(grep "^##?" "$HOME_DIR/src/main.sh" | cut -c 5-)" : "$@")" + local github_token open_ai_api_key gpt_model_name github_api_url files_to_ignore + eval "$(docpars -h "$(grep "^##?" "${BASH_SOURCE[0]}" | cut -c 5-)" : "$@")" utils::verify_required_env_vars @@ -21,21 +24,21 @@ main() { export OPEN_AI_API_KEY="$open_ai_api_key" export GPT_MODEL="$gpt_model_name" - local -r pr_number=$(github::get_pr_number) - local -r commit_diff=$(github::get_commit_diff "$pr_number" "${files_to_ignore[*]}") + local pr_number commit_diff gpt_response + pr_number=$(github::get_pr_number) + commit_diff=$(github::get_commit_diff "$pr_number" "${files_to_ignore[*]}") - if [ -z "$commit_diff" ]; then + if [[ -z "$commit_diff" ]]; then utils::log_info "Nothing in the commit diff." - exit + exit 0 fi - local -r gpt_response=$(gpt::prompt_model "$commit_diff") + gpt_response=$(gpt::prompt_model "$commit_diff") - if [ -z "$gpt_response" ]; then - utils::log_error "GPT's response was NULL. Double check your API key and billing details." + if [[ -z "$gpt_response" ]]; then + utils::log_error "GPT's response was empty. Double check your API key and billing details." + exit 1 fi github::comment "$gpt_response" "$pr_number" - - exit $? } diff --git a/src/utils.sh b/src/utils.sh index 087b259..afee402 100755 --- a/src/utils.sh +++ b/src/utils.sh @@ -1,25 +1,37 @@ #!/usr/bin/env bash +# ANSI color codes +readonly RED='\e[1;91m' +readonly BLUE='\e[1;94m' +readonly RESET='\e[0m' + utils::log_info() { - echo -e "[\\e[1;94mINFO\\e[0m] $@" + printf "[${BLUE}INFO${RESET}] %s\n" "$*" } utils::log_error() { - echo -e "[\\e[1;91mERROR\\e[0m] $@" 1>&2 + printf "[${RED}ERROR${RESET}] %s\n" "$*" >&2 exit 1 } utils::verify_required_env_vars() { - utils::env_variable_exist "GITHUB_REPOSITORY" - utils::env_variable_exist "GITHUB_EVENT_PATH" - utils::env_variable_exist "github_token" - utils::env_variable_exist "github_api_url" - utils::env_variable_exist "open_ai_api_key" - utils::env_variable_exist "gpt_model_name" + local required_vars=( + "GITHUB_REPOSITORY" + "GITHUB_EVENT_PATH" + "github_token" + "github_api_url" + "open_ai_api_key" + "gpt_model_name" + ) + + for var in "${required_vars[@]}"; do + utils::env_variable_exist "$var" + done } utils::env_variable_exist() { - if [[ -z "${!1}" ]]; then - utils::log_error "The env variable '$1' is required." + local var_name="$1" + if [[ -z "${!var_name}" ]]; then + utils::log_error "The env variable '$var_name' is required." fi }