Files
tkmind_go/documentation/automation/recipe-schema-tracking/scripts/diff-validation-structures.sh
T

213 lines
6.5 KiB
Bash
Executable File

#!/bin/bash
# Compare two validation structure files and output changes
# Usage: ./diff-validation-structures.sh old-validation-structure.json new-validation-structure.json
# Output: validation-changes.json
set -e
OLD_FILE=${1:-"old-validation-structure.json"}
NEW_FILE=${2:-"new-validation-structure.json"}
if [ ! -f "$OLD_FILE" ]; then
echo "Error: Old validation structure file not found: $OLD_FILE" >&2
exit 1
fi
if [ ! -f "$NEW_FILE" ]; then
echo "Error: New validation structure file not found: $NEW_FILE" >&2
exit 1
fi
# Extract versions for metadata
OLD_VERSION=$(jq -r '.version' "$OLD_FILE")
NEW_VERSION=$(jq -r '.version' "$NEW_FILE")
# Build the changes JSON using jq
jq -n \
--arg old_version "$OLD_VERSION" \
--arg new_version "$NEW_VERSION" \
--arg compared_at "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
--argjson old_data "$(cat "$OLD_FILE")" \
--argjson new_data "$(cat "$NEW_FILE")" \
'
{
old_version: $old_version,
new_version: $new_version,
compared_at: $compared_at,
has_changes: false,
changes: {
struct_fields: {
added: [],
removed: [],
type_changed: [],
comment_changed: []
},
validation_functions: {
added: [],
removed: [],
signature_changed: [],
error_messages_changed: []
}
}
} |
# Detect field changes
. as $result |
# Find added fields (in new but not in old) - compare by struct.field
($new_data.struct_fields | map(.struct + "." + .field)) as $new_fields |
($old_data.struct_fields | map(.struct + "." + .field)) as $old_fields |
($new_fields - $old_fields) as $added_field_keys |
# Find removed fields (in old but not in new) - compare by struct.field
($old_fields - $new_fields) as $removed_field_keys |
# Find fields with type changes - compare by struct.field
(
$new_data.struct_fields |
map(select((.struct + "." + .field) as $key | $old_fields | contains([$key])) |
{struct: .struct, field: .field, new_type: .type, new_comment: .inline_comment}
)
) as $new_common |
(
$old_data.struct_fields |
map(select((.struct + "." + .field) as $key | $new_fields | contains([$key])) |
{struct: .struct, field: .field, old_type: .type, old_comment: .inline_comment}
)
) as $old_common |
# Compare types and comments for common fields
(
$new_common | map(
. as $new_item |
($old_common | map(select(.struct == $new_item.struct and .field == $new_item.field)) | .[0]) as $old_item |
if $old_item.old_type != $new_item.new_type then
{
struct: $new_item.struct,
field: $new_item.field,
old_type: $old_item.old_type,
new_type: $new_item.new_type
}
else
empty
end
)
) as $type_changed |
(
$new_common | map(
. as $new_item |
($old_common | map(select(.struct == $new_item.struct and .field == $new_item.field)) | .[0]) as $old_item |
if $old_item.old_comment != $new_item.new_comment then
{
struct: $new_item.struct,
field: $new_item.field,
old_comment: $old_item.old_comment,
new_comment: $new_item.new_comment
}
else
empty
end
)
) as $comment_changed |
# Find validation function changes
($new_data.validation_functions | map(.function)) as $new_funcs |
($old_data.validation_functions | map(.function)) as $old_funcs |
($new_funcs - $old_funcs) as $added_funcs |
($old_funcs - $new_funcs) as $removed_funcs |
# Find functions with signature changes
(
$new_data.validation_functions |
map(select(.function as $f | $old_funcs | contains([$f])) |
{function: .function, new_signature: .signature, new_errors: .error_messages}
)
) as $new_common_funcs |
(
$old_data.validation_functions |
map(select(.function as $f | $new_funcs | contains([$f])) |
{function: .function, old_signature: .signature, old_errors: .error_messages}
)
) as $old_common_funcs |
(
$new_common_funcs | map(
. as $new_func |
($old_common_funcs | map(select(.function == $new_func.function)) | .[0]) as $old_func |
if $old_func.old_signature != $new_func.new_signature then
{
function: $new_func.function,
old_signature: $old_func.old_signature,
new_signature: $new_func.new_signature
}
else
empty
end
)
) as $signature_changed |
(
$new_common_funcs | map(
. as $new_func |
($old_common_funcs | map(select(.function == $new_func.function)) | .[0]) as $old_func |
if $old_func.old_errors != $new_func.new_errors then
{
function: $new_func.function,
old_errors: $old_func.old_errors,
new_errors: $new_func.new_errors
}
else
empty
end
)
) as $error_messages_changed |
# Build final result with detected changes
.changes.struct_fields.added = (
$added_field_keys | map(
. as $key |
($key | split(".")) as $parts |
$new_data.struct_fields | map(select(.struct == $parts[0] and .field == $parts[1])) | .[0]
)
) |
.changes.struct_fields.removed = (
$removed_field_keys | map(
. as $key |
($key | split(".")) as $parts |
$old_data.struct_fields | map(select(.struct == $parts[0] and .field == $parts[1])) | .[0]
)
) |
.changes.struct_fields.type_changed = $type_changed |
.changes.struct_fields.comment_changed = $comment_changed |
.changes.validation_functions.added = (
$added_funcs | map(
. as $func |
$new_data.validation_functions | map(select(.function == $func)) | .[0]
)
) |
.changes.validation_functions.removed = (
$removed_funcs | map(
. as $func |
$old_data.validation_functions | map(select(.function == $func)) | .[0]
)
) |
.changes.validation_functions.signature_changed = $signature_changed |
.changes.validation_functions.error_messages_changed = $error_messages_changed |
# Set has_changes flag
.has_changes = (
(.changes.struct_fields.added | length) > 0 or
(.changes.struct_fields.removed | length) > 0 or
(.changes.struct_fields.type_changed | length) > 0 or
(.changes.struct_fields.comment_changed | length) > 0 or
(.changes.validation_functions.added | length) > 0 or
(.changes.validation_functions.removed | length) > 0 or
(.changes.validation_functions.signature_changed | length) > 0 or
(.changes.validation_functions.error_messages_changed | length) > 0
)
'