diff --git a/.github/workflows/update-calendar.yml b/.github/workflows/update-calendar.yml index ce283e8..99e0935 100644 --- a/.github/workflows/update-calendar.yml +++ b/.github/workflows/update-calendar.yml @@ -42,17 +42,16 @@ jobs: - name: "Check diff" id: check_diff run: | - curl -sSL "https://calendar.ifsc.stream/?format=json&nocache=1" --output current-calendar.json + curl -sSL "https://calendar.ifsc.stream/?format=json&nocache=1" --output old-calendar.json if [ $(jq '.events | length' "${{ env.CALENDAR_FILE_JSON }}") -lt 9 ]; then echo "Too few events found in current calendar" exit 1 fi - diff -C 3 current-calendar.json "${{ env.CALENDAR_FILE_JSON }}" > calendar.diff || true + php bin/calendar-diff old-calendar.json "${{ env.CALENDAR_FILE_JSON }}" > diff.md || true - if [ $(wc -w < calendar.diff) -gt 0 ]; then - echo -e "Changes:\n\`\`\`diff\n$(cat calendar.diff)\n\`\`\`" > calendar.diff + if [ $(wc -w < diff.md) -gt 0 ]; then echo "has_changes=true" >> $GITHUB_OUTPUT else echo "has_changes=false" >> $GITHUB_OUTPUT @@ -74,7 +73,7 @@ jobs: ${{ env.CALENDAR_FILE_JSON }} tag_name: ${{ steps.date.outputs.tag_name }} name: ${{ steps.date.outputs.name }} - body_path: calendar.diff + body_path: diff.md - name: "Run latest-tag" if: steps.check_diff.outputs.has_changes == 'true' diff --git a/bin/calendar-diff b/bin/calendar-diff new file mode 100755 index 0000000..d921651 --- /dev/null +++ b/bin/calendar-diff @@ -0,0 +1,256 @@ +#!/usr/bin/env php + + */ + +function generate_start_list_diff(array $oldStartList, array $newStartList): string +{ + if ($oldStartList === $newStartList) { + return ''; + } + + $diff = ''; + + foreach ($newStartList as $key => $athlete) { + if (isset($oldStartList[$key])) { + if ($athlete !== $oldStartList[$key]) { + $diff .= "|Replaced|{$oldStartList[$key]['first_name']}|{$oldStartList[$key]['last_name']}|{$athlete['first_name']}|{$athlete['last_name']}" . PHP_EOL; + } + } else { + $diff .= "|Added|{$athlete['first_name']}|{$athlete['last_name']}|---|---|" . PHP_EOL; + } + } + + foreach ($oldStartList as $key => $athlete) { + if (!isset($newStartList[$key])) { + $diff .= "|Removed|{$athlete['first_name']}|{$athlete['last_name']}|---|---|" . PHP_EOL; + } + } + + return $diff; +} + +function normalize_value(mixed $value): string +{ + if (empty($value)) { + return 'null'; + } + + if (is_array($value)) { + $value = implode(', ', $value); + } + + return (string) $value; +} + +function find_round_by_name(array $oldRounds, string $name): ?array +{ + foreach ($oldRounds as $oldRound) { + if ($oldRound['name'] === $name) { + return $oldRound; + } + } + + return null; +} + +function get_event_by_id(array $events, int $eventId): ?array +{ + foreach ($events as $event) { + if ($event['id'] === $eventId) { + return $event; + } + } + + return null; +} + +function normalize_events_from_file(string $fileName): array +{ + return json_decode(file_get_contents($fileName), associative: true)['events']; +} + +function generate_round_diff(array $oldRounds, array $newRounds): string +{ + $diff = ''; + $changedRounds = ''; + $addedRounds = ''; + + foreach ($newRounds as $newRound) { + $oldRound = find_round_by_name($oldRounds, $newRound['name']); + + if (!$oldRound) { + foreach ($newRound as $value) { + $addedRounds .= "|" . normalize_value($value); + } + + $addedRounds .= "|" . PHP_EOL; + } else { + $roundDiff = ''; + foreach ($newRound as $key => $newValue) { + $oldValue = $oldRound[$key]; + + if ($newValue !== $oldValue) { + $roundDiff .= "|{$key} |" . normalize_value($oldValue) . "|" . normalize_value($newValue) . "|" . PHP_EOL; + } + } + + if ($roundDiff) { + $changedRounds .= "| {$newRound['name']} |--- |--- |" . PHP_EOL; + $changedRounds .= "|-----------------------|---------------|-----------------|" . PHP_EOL; + $changedRounds .= "| **Key** | **Old Value** | **New Value** |" . PHP_EOL; + $changedRounds .= $roundDiff . PHP_EOL; + } + } + } + + if ($changedRounds) { + $diff .= PHP_EOL; + $diff .= "#### Changed Rounds" . PHP_EOL; + $diff .= $changedRounds; + } + + if ($addedRounds) { + $diff .= "#### Added Rounds" . PHP_EOL; + $diff .= "|" . implode('|', array_keys($newRounds[0])) . "|" . PHP_EOL; + $diff .= "|" . str_repeat('-------------|', count($newRounds[0])) . PHP_EOL; + $diff .= $addedRounds . PHP_EOL . PHP_EOL; + } + + return $diff; +} + +$oldEvents = normalize_events_from_file($argv[1]); +$newEvents = normalize_events_from_file($argv[2]); + +$diff = ''; +$addedEvents = ''; +$removedEvents = ''; + +foreach ($newEvents as $newEvent) { + if (!get_event_by_id($oldEvents, $newEvent['id'])) { + $addedEvents .= "### 🏆 {$newEvent['name']}" . PHP_EOL; + $addedEvents .= "|Key|Value|" . PHP_EOL; + $addedEvents .= "|---|-----|" . PHP_EOL; + + foreach ($newEvent as $key => $value) { + if ($key === 'rounds' || $key === 'start_list') { + continue; + } + + $addedEvents .= "|$key|" . normalize_value($value) ."|" . PHP_EOL; + } + + $addedEvents .= PHP_EOL; + $addedEvents .= "#### đŸŽ¯ Rounds:" . PHP_EOL; + $addedEvents .= "|" . implode('|', array_keys($newEvent['rounds'][0])) . "|" . PHP_EOL; + $addedEvents .= "|" . str_repeat('-------------|', count($newEvent['rounds'][0])) . PHP_EOL; + + foreach ($newEvent['rounds'] as $round) { + foreach ($round as $value) { + $addedEvents .= "|" . normalize_value($value); + } + $addedEvents .= "|" . PHP_EOL; + } + + $addedEvents .= PHP_EOL; + $addedEvents .= "#### 📋 Start List:" . PHP_EOL; + $addedEvents .= "|" . implode('|', array_keys($newEvent['start_list'][0])) . "|" . PHP_EOL; + $addedEvents .= "|" . str_repeat('-------------|', count($newEvent['start_list'][0])) . PHP_EOL; + + foreach ($newEvent['start_list'] as $startList) { + foreach ($startList as $value) { + $addedEvents .= "|" . normalize_value($value); + } + $addedEvents .= "|" . PHP_EOL; + } + } +} + +foreach ($oldEvents as $oldEvent) { + if (!get_event_by_id($newEvents, $oldEvent['id'])) { + $removedEvents .= "|🏆 {$oldEvent['name']}|---|--- |" . PHP_EOL; + $removedEvents .= "|-------------|---------|-------|" . PHP_EOL; + $removedEvents .= "|**Round** |**Starts At**|**Ends At**|" . PHP_EOL; + + foreach ($oldEvent['rounds'] as $round) { + $removedEvents .= "|{$round['name']}|{$round['starts_at']}|{$round['ends_at']}" . PHP_EOL; + } + + $removedEvents .= PHP_EOL; + } +} + +if ($addedEvents) { + $diff .= "🎉 Added Events:" . PHP_EOL; + $diff .= "===============" . PHP_EOL; + $diff .= $addedEvents . PHP_EOL; +} + +if ($removedEvents) { + $diff .= "🗑ī¸ Removed Events:" . PHP_EOL; + $diff .= "===============" . PHP_EOL; + $diff .= $removedEvents . PHP_EOL; +} + +$changedEvents = ''; + +foreach ($newEvents as $newEvent) { + $oldEvent = get_event_by_id($oldEvents, $newEvent['id']); + + if (!$oldEvent) { + continue; + } + + $newDiff = ''; + $roundDiff = ''; + $startListDiff = ''; + + foreach ($newEvent as $key => $value) { + if ($key === 'rounds') { + $roundDiff .= generate_round_diff($oldEvent[$key], $value); + } elseif ($key === 'start_list') { + $startListDiff .= generate_start_list_diff($oldEvent[$key], $value); + } elseif (normalize_value($value) !== normalize_value($oldEvent[$key])) { + $newDiff .= "|$key|" . normalize_value($oldEvent[$key]) ."|" . normalize_value($value) . "|" . PHP_EOL; + } + } + + if ($newDiff || $roundDiff || $startListDiff) { + $changedEvents .= "#### 🏆 {$newEvent['name']}" . PHP_EOL; + + if ($newDiff) { + $changedEvents .= "| ℹī¸ Event Details | --- | --- |" . PHP_EOL; + $changedEvents .= "|------------------------|---------------|----------------|" . PHP_EOL; + $changedEvents .= "| **Key** | **Old Value** | **New Value** |" . PHP_EOL; + $changedEvents .= $newDiff; + } + + if ($roundDiff) { + $changedEvents .= PHP_EOL; + $changedEvents .= $roundDiff; + } + + if ($startListDiff) { + $changedEvents .= PHP_EOL; + $changedEvents .= "| 📋 Start List | --- | --- | --- | --- |" . PHP_EOL; + $changedEvents .= "|---------------|-----------------|---------------|--------------------|-------------------|" . PHP_EOL; + $changedEvents .= "| **Status** | **First Name** | **Last Name** | **New First Name** | **New Last Name** |" . PHP_EOL; + $changedEvents .= $startListDiff . PHP_EOL; + } + + $changedEvents .= PHP_EOL; + } +} + +if ($changedEvents) { + $diff .= "✏ī¸ Changed Events:" . PHP_EOL; + $diff .= "==================" . PHP_EOL; + $diff .= $changedEvents; +} + +echo $diff;