213 lines
6.5 KiB
Bash
Executable File
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
|
|
)
|
|
'
|
|
|
|
|