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;