diff --git a/conditional-variables/evaluate.sh b/conditional-variables/evaluate.sh index 1c5c9d5..66f7e88 100644 --- a/conditional-variables/evaluate.sh +++ b/conditional-variables/evaluate.sh @@ -1,14 +1,16 @@ declare -A context +declare -A outputs +declare -a output_names + +matched_any=false echo "=== CONTEXT ===" -printf '%s\n' "$CONTEXT" +printf '%s\n' "${CONTEXT:-}" echo echo "=== RULES ===" -printf '%s\n' "$RULES" -# -# Remove leading/trailing whitespace -# +printf '%s\n' "${RULES:-}" + trim() { local var="$*" var="${var#"${var%%[![:space:]]*}"}" @@ -16,13 +18,11 @@ trim() { printf '%s' "$var" } -# -# Load key=value pairs into context array -# load_context() { + local key + local value while IFS='=' read -r key value; do - key="$(trim "${key:-}")" value="$(trim "${value:-}")" @@ -30,20 +30,10 @@ load_context() { [[ "$key" =~ ^# ]] && continue context["$key"]="$value" - - done <<< "$CONTEXT" + done <<< "${CONTEXT:-}" } -# -# Evaluate a single condition -# -# Examples: -# branch == 9.0 -# event != push -# count > 10 -# evaluate_condition() { - local condition="$1" local variable @@ -65,8 +55,9 @@ evaluate_condition() { actual="${context[$variable]}" - case "$operator" in + echo "Evaluating: '$variable' actual='$actual' operator='$operator' expected='$expected'" + case "$operator" in "==") [[ "$actual" == "$expected" ]] ;; @@ -74,21 +65,20 @@ evaluate_condition() { "!=") [[ "$actual" != "$expected" ]] ;; - + "contains") [[ "$actual" == *"$expected"* ]] ;; - + "startsWith") [[ "$actual" == "$expected"* ]] ;; - + "endsWith") [[ "$actual" == *"$expected" ]] ;; ">"|">="|"<"|"<=") - if [[ ! "$actual" =~ ^-?[0-9]+$ ]]; then echo "Numeric operator '$operator' requires integer value. Actual: '$actual'" return 1 @@ -122,74 +112,102 @@ evaluate_condition() { esac } -# -# Evaluate list of conditions -# -# Conditions are OR'd together -# evaluate_conditions() { - - local matched=false + local conditions="$1" + local condition while IFS= read -r condition; do - condition="$(trim "${condition:-}")" [[ -z "$condition" ]] && continue [[ "$condition" =~ ^# ]] && continue if evaluate_condition "$condition"; then - matched=true - break + return 0 fi + done <<< "$conditions" - done <<< "$CONDITIONS" - - [[ "$matched" == true ]] + return 1 +} + +store_output() { + local output="$1" + local name + local value + + output="$(trim "${output:-}")" + + [[ -z "$output" ]] && return 0 + [[ "$output" =~ ^# ]] && return 0 + + if [[ ! "$output" =~ ^[A-Za-z_][A-Za-z0-9_]*= ]]; then + echo "Invalid variable definition: $output" + return 1 + fi + + name="${output%%=*}" + value="${output#*=}" + + if [[ ! -v outputs["$name"] ]]; then + output_names+=("$name") + fi + + outputs["$name"]="$value" + + echo "Set output candidate: $name=$value" } -# -# Write outputs -# apply_variables() { + local variables="$1" + local output while IFS= read -r output; do - - output="$(trim "${output:-}")" - - [[ -z "$output" ]] && continue - [[ "$output" =~ ^# ]] && continue - - if [[ ! "$output" =~ ^[A-Za-z_][A-Za-z0-9_]*= ]]; then - echo "Invalid variable definition: $output" - return 1 - fi - - echo "$output" >> "$GITHUB_OUTPUT" - - done <<< "$VARIABLES" + store_output "$output" + done <<< "$variables" } -# -# Main -# -main() { +finalize_rule() { + local conditions="$1" + local variables="$2" - load_context + conditions="$(trim "$conditions")" + variables="$(trim "$variables")" - local matched=false + [[ -z "$conditions" && -z "$variables" ]] && return 0 - if evaluate_conditions; then - matched=true - apply_variables + echo + echo "=== PARSED RULE ===" + echo "--- conditions ---" + printf '%s\n' "$conditions" + echo "--- set ---" + printf '%s\n' "$variables" + + if [[ -z "$conditions" ]]; then + echo "Rule has no conditions, skipping" + return 0 fi - if [[ "$matched" == false && "$FAIL_ON_NO_MATCH" == "true" ]]; then - echo "No conditions matched" - exit 1 + if [[ -z "$variables" ]]; then + echo "Rule has no variables to set, skipping" + return 0 fi - echo "matched=$matched" >> "$GITHUB_OUTPUT" + if evaluate_conditions "$conditions"; then + echo "Rule matched" + matched_any=true + apply_variables "$variables" + else + echo "Rule did not match" + fi } -main \ No newline at end of file +parse_rules() { + local line + local current_conditions="" + local current_variables="" + local mode="" + + while IFS= read -r line; do + line="$(trim "${line:-}")" + + [[ -z "$line" ]] && continue \ No newline at end of file