/ maint / crates-io-utils.sh
crates-io-utils.sh
 1  # Utilities for querying crates.io
 2  
 3  # Shellcheck is confused.
 4  # It thinks it ought to be checking this as a standalone script, and prints
 5  #   -- SC2148 (error): Tips depend on target shell and yours is unknown.
 6  #             Add a shebang or a 'shell' directive.
 7  # shellcheck shell=bash
 8  
 9  CRATES_IO_URL_BASE=https://crates.io/api
10  
11  fail () {
12      echo >&2 "$0: error: $*"
13      exit 12
14  }
15  
16  tmp_trap_exit_setup () {
17      if [ "x$MAINT_DDLETE_CREATE_TMP" != x ]; then
18  	rm -rf -- "$MAINT_DDLETE_CREATE_TMP"
19  	mkdir -- "$MAINT_DDLETE_CREATE_TMP"
20  	tmp="$MAINT_DDLETE_CREATE_TMP"
21      else
22  	tmp=$(mktemp -d)
23  	trap 'set +e; rm -rf "$tmp"; exit $exit_rc' 0
24      fi
25      exit_rc=8
26  }
27  
28  tmp_trap_exit_finish_status () {
29      exit_rc=$1
30  }
31  
32  tmp_trap_exit_finish_ok () {
33      tmp_trap_exit_finish_status 0
34  }
35  
36  # Queries
37  #   https://crates.io/api/$endpoint
38  # Expects to receive either
39  #   HTTP 200 and a json document which `jq "$expect_key"` accepts
40  #   HTTP 404 and a json document containing a `.errors` key
41  # The fetched document is stored in "$output"
42  # The HTTP code is left in the global variable `http_code`
43  # (and also written to "$output.http")
44  #
45  # There is a Python reimplementation `cargo-check-publishable`
46  # TODO: possibly, break that function out into a library and
47  #       replace this shell implementation with a veneer over the Python one.
48  crates_io_api_call () {
49      local endpoint="$1"
50      local expect_key="$2"
51      local output="$3"
52  
53      local url="${CRATES_IO_URL_BASE}/$endpoint"
54  
55      sleep 1
56      curl -A 'maint/ scripts for Tor Project CI (shell script)' \
57  	 -L -sS -o "$output" -w '%{http_code}' >"$output.http" "$url"
58      http_code=$(cat "$output.http")
59  
60      case "$http_code" in
61  	200) expect="$expect_key" ;;
62  	404) expect=.errors ;;
63  	*)
64  	    cat -vet "$output" >&2
65  	    fail "unexpected HTTP response status code $http_code from $url"
66  	    ;;
67      esac
68  
69      set +e
70      jq -e "$expect" <"$output" >/dev/null
71      jq_rc=$?
72      set -e
73      if [ $jq_rc != 0 ]; then
74  	cat -vet "$output" >&2
75  	fail "bad JSON data from $url (expected $expect)"
76      fi
77  }