master
sh 86 lines 3.12 KB
Raw
1 #!/usr/bin/env bash
2 # Fetch per-defect details from Coverity Scan for each CID in a table.json dump.
3 #
4 # Usage:
5 # fetch-details.sh <input-defects.json> <output-dir>
6 #
7 # Reads cookies/XSRF/UA from .env via _lib.sh.
8 # For each row, calls /sourcebrowser/defectdetails.json?defectInstanceId=<lastDefectInstanceId>.
9 # Skips rows whose output file already exists (idempotent; safe to re-run).
10
11 set -euo pipefail
12
13 # shellcheck source=./_lib.sh
14 # shellcheck disable=SC1091
15 source "$(dirname "$0")/_lib.sh"
16 cov_load_env
17
18 INPUT="${1:?usage: $0 <input-defects.json> <output-dir>}"
19 OUT_DIR="${2:?usage: $0 <input-defects.json> <output-dir>}"
20
21 if [[ ! -f "${INPUT}" || ! -r "${INPUT}" ]]; then
22 echo -e "${COV_RED}[ERROR]${COV_NC} input file not a readable regular file: '${INPUT}'" >&2
23 exit 1
24 fi
25
26 mkdir -p "${OUT_DIR}"
27
28 TOTAL="$(jq 'length' "${INPUT}")"
29 echo -e "${COV_GRAY}Fetching details for ${TOTAL} defects into ${OUT_DIR}${COV_NC}" >&2
30
31 i=0
32 fetched=0
33 skipped=0
34 failed=0
35
36 while IFS=$'\t' read -r cid defect_instance_id; do
37 i=$((i + 1))
38 # cid comes from the input JSON (Coverity-supplied) and lands in the
39 # output filename. Validate numeric before path construction so a
40 # corrupted/manipulated INPUT cannot write outside OUT_DIR.
41 if [[ ! "${cid}" =~ ^[1-9][0-9]*$ ]]; then
42 failed=$((failed + 1))
43 echo -e "${COV_RED}[${i}/${TOTAL}] non-numeric cid in input: '${cid}' -- skipping${COV_NC}" >&2
44 continue
45 fi
46 if [[ ! "${defect_instance_id}" =~ ^[1-9][0-9]*$ ]]; then
47 failed=$((failed + 1))
48 echo -e "${COV_RED}[${i}/${TOTAL}] cid=${cid} non-numeric defectInstanceId: '${defect_instance_id}' -- skipping${COV_NC}" >&2
49 continue
50 fi
51 out_file="${OUT_DIR}/cid-${cid}.json"
52 if [[ -s "${out_file}" ]]; then
53 skipped=$((skipped + 1))
54 continue
55 fi
56 sleep 0.3
57
58 http_code="$(curl -sS --max-time 30 \
59 -w '%{http_code}' \
60 -o "${out_file}" \
61 -H "accept: application/json, text/plain, */*" \
62 -H "referer: ${COVERITY_HOST}/" \
63 -H "user-agent: ${COVERITY_USER_AGENT}" \
64 -H "x-xsrf-token: ${COVERITY_XSRF}" \
65 -b "${COVERITY_COOKIE}" \
66 "${COVERITY_HOST}/sourcebrowser/defectdetails.json?projectId=${COVERITY_PROJECT_ID}&defectInstanceId=${defect_instance_id}" || echo "000")"
67
68 if [[ "${http_code}" != "200" ]]; then
69 failed=$((failed + 1))
70 echo -e "${COV_RED}[${i}/${TOTAL}] cid=${cid} diid=${defect_instance_id} HTTP=${http_code}${COV_NC}" >&2
71 if [[ "${http_code}" == "401" || "${http_code}" == "403" ]]; then
72 echo -e "${COV_RED}Session likely expired. Recapture cookie from browser, update .env, retry.${COV_NC}" >&2
73 rm -f "${out_file}"
74 exit 2
75 fi
76 rm -f "${out_file}"
77 continue
78 fi
79
80 fetched=$((fetched + 1))
81 if (( i % 20 == 0 )); then
82 echo -e "${COV_GRAY}[${i}/${TOTAL}] fetched=${fetched} skipped=${skipped} failed=${failed}${COV_NC}" >&2
83 fi
84 done < <(jq -r '.[] | "\(.cid)\t\(.lastDefectInstanceId)"' "${INPUT}")
85
86 echo -e "${COV_GREEN}Done. fetched=${fetched} skipped=${skipped} failed=${failed} total=${TOTAL}${COV_NC}" >&2