@@ -457,7 +457,6 @@ ytoxt() {
457457 local f=" $1 "
458458 local tmp
459459 local del_n=1
460- local last_json_size=-1
461460 local last_xml_size=-1
462461
463462 [ -f " $f " ] || return 1
@@ -468,18 +467,16 @@ ytoxt() {
468467 while [ -f " $f " ]; do
469468 local json_size
470469 local xml_size
470+ local tmp_size
471471
472472 json_size=$( stat -c %s " $f " 2> /dev/null || echo -1)
473473
474- # Stop if we can't shrink anymore.
475- if [ " $json_size " -eq " $last_json_size " ] && [ " $last_json_size " -ge 0 ]; then
476- break
477- fi
478- last_json_size=" $json_size "
479-
480474 if [ " $json_size " -lt 50000000 ]; then
481475 # Only generate/check XML if JSON is already under limit.
482476 xml_size=$( ytox " $f " 2> /dev/null || echo -1)
477+ # If XML size can't be determined, treat it as oversized so we keep trimming.
478+ [ " $xml_size " -ge 0 ] || xml_size=50000000
479+
483480 if [ " $xml_size " -lt 50000000 ]; then
484481 break
485482 fi
@@ -489,6 +486,11 @@ ytoxt() {
489486 break
490487 fi
491488 last_xml_size=" $xml_size "
489+
490+ # XML still too large: increase trimming aggressiveness as well.
491+ if [ " $del_n " -lt 65536 ]; then
492+ del_n=$(( del_n * 2 ))
493+ fi
492494 else
493495 # JSON is still too large: increase trimming aggressiveness.
494496 if [ " $json_size " -ge 50000000 ]; then
@@ -499,7 +501,7 @@ ytoxt() {
499501 fi
500502
501503 if jq -e '
502- if type == "array" then
504+ if ( type == "array") or (type == "object") then
503505 any(.[]; ((.version // []) | type == "array") and ((.version // []) | length > 0))
504506 else
505507 ((.version // []) | type == "array") and ((.version // []) | length > 0)
@@ -510,6 +512,8 @@ ytoxt() {
510512 if type == "number" then .
511513 elif type == "string" then tonumber? // 0
512514 else 0 end;
515+ def vlen:
516+ (.version // []) | if type == "array" then length else 0 end;
513517 def trim_versions($n):
514518 if ((.version // []) | type == "array") and ((.version // []) | length > 0) then
515519 (
@@ -523,14 +527,24 @@ ytoxt() {
523527 end;
524528 if type == "array" then
525529 (to_entries
526- | (max_by(( .value.version // []) | length ) // empty) as $max
530+ | (max_by(.value | vlen ) // empty) as $max
527531 | map(
528- if .key == $max.key and ((( .value.version // []) | type == "array") and ((.value.version // []) | length > 0) )
532+ if .key == $max.key and ((.value | vlen) > 0)
529533 then (.value |= trim_versions($n))
530534 else .
531535 end
532536 )
533537 | map(.value))
538+ elif type == "object" then
539+ (to_entries
540+ | (max_by(.value | vlen) // empty) as $max
541+ | map(
542+ if .key == $max.key and ((.value | vlen) > 0)
543+ then (.value |= trim_versions($n))
544+ else .
545+ end
546+ )
547+ | from_entries)
534548 else
535549 trim_versions($n)
536550 end
@@ -551,12 +565,79 @@ ytoxt() {
551565 [ .[] | select(.key != $target.key) | .value ]
552566 end
553567 )
568+ elif type == "object" then
569+ (
570+ def to_num:
571+ if type == "number" then .
572+ elif type == "string" then tonumber? // 0
573+ else 0 end;
574+ to_entries
575+ | (min_by([ (.value.raw_downloads // 0 | to_num), (.value.date // "") ]) // null) as $target
576+ | if $target == null then
577+ from_entries
578+ else
579+ ([ .[] | select(.key != $target.key) ] | from_entries)
580+ end
581+ )
554582 else
555583 .
556584 end
557585 ' " $f " > " $tmp "
558586 fi
559587
588+ tmp_size=$( stat -c %s " $tmp " 2> /dev/null || echo -1)
589+
590+ # If trimming didn't reduce size, retry with more aggressive deletion instead of stalling.
591+ if [ " $json_size " -ge 0 ] && [ " $tmp_size " -ge 0 ] && [ " $tmp_size " -ge " $json_size " ]; then
592+ rm -f " $tmp "
593+
594+ if [ " $del_n " -lt 65536 ]; then
595+ del_n=$(( del_n * 2 ))
596+ continue
597+ fi
598+
599+ # If we're already at max aggressiveness, fall back to trimming whole packages once.
600+ jq -c '
601+ if type == "array" then
602+ (
603+ def to_num:
604+ if type == "number" then .
605+ elif type == "string" then tonumber? // 0
606+ else 0 end;
607+ to_entries
608+ | (min_by([ (.value.raw_downloads // 0 | to_num), (.value.date // "") ]) // null) as $target
609+ | if $target == null then
610+ map(.value)
611+ else
612+ [ .[] | select(.key != $target.key) | .value ]
613+ end
614+ )
615+ elif type == "object" then
616+ (
617+ def to_num:
618+ if type == "number" then .
619+ elif type == "string" then tonumber? // 0
620+ else 0 end;
621+ to_entries
622+ | (min_by([ (.value.raw_downloads // 0 | to_num), (.value.date // "") ]) // null) as $target
623+ | if $target == null then
624+ from_entries
625+ else
626+ ([ .[] | select(.key != $target.key) ] | from_entries)
627+ end
628+ )
629+ else
630+ .
631+ end
632+ ' " $f " > " $tmp "
633+
634+ tmp_size=$( stat -c %s " $tmp " 2> /dev/null || echo -1)
635+ if [ " $json_size " -ge 0 ] && [ " $tmp_size " -ge 0 ] && [ " $tmp_size " -ge " $json_size " ]; then
636+ rm -f " $tmp "
637+ break
638+ fi
639+ fi
640+
560641 mv " $tmp " " $f "
561642 done
562643
0 commit comments