@@ -20,13 +20,9 @@ fetch_json() {
2020 # Use -s for silent, --max-time for timeout
2121 # -w "\n%{http_code}" appends the HTTP status code on a new line to stdout.
2222 # This helps in reliably separating the body from the status code.
23- response_and_status=$( curl -s --max-time 10 -w " \n%{http_code}" " $url " 2> /dev/null)
24- local curl_exit=$?
25-
26- # Check if curl command itself failed (e.g., network error, timeout before HTTP response)
27- if [[ $curl_exit -ne 0 ]]; then
23+ if ! response_and_status=$( curl -s --max-time 10 -w $' \n %{http_code}' " $url " 2> /dev/null) ; then
2824 echo " Error: curl command failed for $url " >&2
29- return 1 # Indicate failure
25+ return 1
3026 fi
3127
3228 # Ensure we have some output to parse
@@ -35,48 +31,45 @@ fetch_json() {
3531 return 1
3632 fi
3733
38- # Split the response into body and status code based on the newline added by -w
39- # The last line is the status code, everything before it is the body.
40- http_status=$( echo -n " $response_and_status " | tail -n 1)
41- response_body=$( echo -n " $response_and_status " | head -n -1)
34+ # Split response into body and status code using bash string ops (portable across GNU/BSD).
35+ http_status=" ${response_and_status##* $' \n ' } "
36+ response_body=" ${response_and_status% $' \n ' * } "
4237
4338 # Handle 2xx success, 404 as handled empty, and other statuses as errors.
4439 if [[ " $http_status " =~ ^2[0-9][0-9]$ ]]; then
45- echo " $response_body "
40+ printf ' %s ' " $response_body "
4641 sleep " $REQUEST_DELAY " # Be polite
4742 return 0
4843 elif [[ " $http_status " == " 404" ]]; then
4944 # Crate or version not found. This is a handled case, not necessarily an error for the script's logic.
50- echo " "
45+ printf ' %s ' " "
5146 sleep " $REQUEST_DELAY "
5247 return 0
5348 else
5449 echo " Error: Failed to fetch $url . HTTP Status: $http_status . Response: ${response_body: 0: 100} ..." >&2
55- return 1 # Indicate failure
50+ return 1
5651 fi
5752}
5853
5954# Only run main when executed directly, not when sourced by tests
6055if [[ " ${BASH_SOURCE[0]} " == " $0 " ]]; then
6156 # Main script logic
62- if [[ " \$ # " -eq 0 ]]; then
57+ if [[ $# -eq 0 ]]; then
6358 echo " Usage: $0 <crate_name_1> [crate_name_2] ..." >&2
6459 exit 1
6560 fi
6661
67- for crate_name in " \ $ @" ; do
62+ for crate_name in " $@ " ; do
6863 # 1. Try to get max_version from /api/v1/crates/{name}
6964 CRATE_INFO_URL=" ${CRATES_IO_API_BASE} /crates/${crate_name} "
70- crate_info_json=$( fetch_json " $CRATE_INFO_URL " )
71-
72- if [[ $? -ne 0 ]]; then # Check if fetch_json itself failed (e.g., curl error)
65+ if ! crate_info_json=$( fetch_json " $CRATE_INFO_URL " ) ; then
7366 echo " Skipping '$crate_name ': Failed to retrieve crate info due to network/curl error." >&2
7467 continue
7568 fi
7669
7770 target_version=" "
7871 if [[ -n " $crate_info_json " ]]; then
79- max_version=$( echo " $crate_info_json " | jq -r ' .crate.max_version // empty' )
72+ max_version=$( printf ' %s ' " $crate_info_json " | jq -r ' .crate.max_version // empty' )
8073 if [[ -n " $max_version " ]]; then
8174 target_version=" $max_version "
8275 fi
@@ -85,16 +78,14 @@ if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
8578 if [[ -z " $target_version " ]]; then
8679 # 2. If max_version is empty or not found, fetch all versions and pick the first non-yanked one
8780 VERSIONS_URL=" ${CRATES_IO_API_BASE} /crates/${crate_name} /versions"
88- versions_json=$( fetch_json " $VERSIONS_URL " )
89-
90- if [[ $? -ne 0 ]]; then
81+ if ! versions_json=$( fetch_json " $VERSIONS_URL " ) ; then
9182 echo " Skipping '$crate_name ': Failed to retrieve versions list due to network/curl error." >&2
9283 continue
9384 fi
9485
9586 if [[ -n " $versions_json " ]]; then
9687 # Find the first non-yanked version number
97- target_version=$( echo " $versions_json " | jq -r ' .versions[] | select(.yanked == false) | .num' | head -n 1)
88+ target_version=$( printf ' %s ' " $versions_json " | jq -r ' .versions[] | select(.yanked == false) | .num' | head -n 1)
9889 fi
9990
10091 if [[ -z " $target_version " ]]; then
@@ -105,9 +96,7 @@ if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
10596
10697 # 3. Now that we have a target_version, fetch its metadata and check features
10798 VERSION_METADATA_URL=" ${CRATES_IO_API_BASE} /crates/${crate_name} /${target_version} "
108- version_metadata_json=$( fetch_json " $VERSION_METADATA_URL " )
109-
110- if [[ $? -ne 0 ]]; then
99+ if ! version_metadata_json=$( fetch_json " $VERSION_METADATA_URL " ) ; then
111100 echo " Skipping '$crate_name ': Failed to retrieve metadata for version '$target_version ' due to network/curl error." >&2
112101 continue
113102 fi
@@ -118,7 +107,7 @@ if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
118107 fi
119108
120109 # Check if the features map is non-empty
121- feature_count=$( echo " $version_metadata_json " | jq -r ' .version.features | to_entries | length // 0' )
110+ feature_count=$( printf ' %s ' " $version_metadata_json " | jq -r ' .version.features | to_entries | length // 0' )
122111
123112 if [[ " $feature_count " -gt 0 ]]; then
124113 echo " $crate_name "
0 commit comments