Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at devShellTools-shell 260 lines 9.2 kB view raw
1#!/usr/bin/env nix-shell 2#!nix-shell -i bash -p coreutils git nix curl jq 3# shellcheck shell=bash enable=all 4 5set -e 6shopt -s inherit_errexit 7 8# this script will generate versions.nix in the right location 9# this should contain the versions' revs and hashes 10# the stable revs are stored only for ease of skipping 11 12# by default nix-prefetch-url uses XDG_RUNTIME_DIR as tmp 13# which is /run/user/1000, which defaults to 10% of your RAM 14# unless you have over 64GB of ram that'll be insufficient 15# resulting in "tar: no space left on device" for packages3d 16# hence: 17export TMPDIR=/tmp 18 19# if something goes unrepairably wrong, run 'update.sh all clean' 20 21# TODO 22# support parallel instances for each pname 23# currently risks reusing old data 24# no getting around manually checking if the build product works... 25# if there is, default to commiting? 26# won't work when running in parallel? 27# remove items left in /nix/store? 28# reuse hashes of already checked revs (to avoid redownloading testing's packages3d) 29 30# nixpkgs' update.nix passes in UPDATE_NIX_PNAME to indicate which package is being updated 31# assigning a default value to that as shellcheck doesn't like the use of unassigned variables 32: "${UPDATE_NIX_PNAME:=""}" 33# update.nix can also parse JSON output of this script to formulate a commit 34# this requires we collect the version string in the old versions.nix for the updated package 35old_version="" 36new_version="" 37 38 39# get the latest tag that isn't an RC or *.99 40latest_tags="$(git ls-remote --tags --sort -version:refname https://gitlab.com/kicad/code/kicad.git)" 41# using a scratch variable to ensure command failures get caught (SC2312) 42scratch="$(grep -o 'refs/tags/[0-9]*\.[0-9]*\.[0-9]*$' <<< "${latest_tags}")" 43scratch="$(grep -ve '\.99' -e '\.9\.9' <<< "${scratch}")" 44scratch="$(sed -n '1p' <<< "${scratch}")" 45latest_tag="$(cut -d '/' -f 3 <<< "${scratch}")" 46 47# get the latest branch name for testing 48branches="$(git ls-remote --heads --sort -version:refname https://gitlab.com/kicad/code/kicad.git)" 49scratch="$(grep -o 'refs/heads/[0-9]*\.[0-9]*$' <<< "${branches}")" 50scratch="$(sed -n '1p' <<< "${scratch}")" 51testing_branch="$(cut -d '/' -f 3 <<< "${scratch}")" 52 53# "latest_tag" and "master" directly refer to what we want 54# "testing" uses "testing_branch" found above 55all_versions=( "${latest_tag}" testing master ) 56 57prefetch="nix-prefetch-url --unpack --quiet" 58 59clean="" 60check_stable="" 61check_testing=1 62check_unstable=1 63commit="" 64 65for arg in "$@" "${UPDATE_NIX_PNAME}"; do 66 case "${arg}" in 67 help|-h|--help) echo "Read me!" >&2; exit 1; ;; 68 kicad|kicad-small|release|tag|stable|5*|6*|7*|8*) check_stable=1; check_testing=""; check_unstable="" ;; 69 *testing|kicad-testing-small) check_testing=1; check_unstable="" ;; 70 *unstable|*unstable-small|master|main) check_unstable=1; check_testing="" ;; 71 latest|now|today) check_unstable=1; check_testing=1 ;; 72 all|both|full) check_stable=1; check_testing=1; check_unstable=1 ;; 73 clean|fix|*fuck) check_stable=1; check_testing=1; check_unstable=1; clean=1 ;; 74 commit) commit=1 ;; 75 *) ;; 76 esac 77done 78 79here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 80commit_date() { 81 gitlab_json="$(curl -s https://gitlab.com/api/v4/projects/kicad%2Fcode%2Fkicad/repository/commits/"$1")" 82 commit_created="$(jq .created_at --raw-output <<< "${gitlab_json}")" 83 date --date="${commit_created}" --iso-8601 --utc 84} 85 86file="${here}/versions.nix" 87# just in case this runs in parallel 88tmp="${here}/,versions.nix.${RANDOM}" 89 90libs=( symbols templates footprints packages3d ) 91 92get_rev() { 93 git ls-remote "$@" 94} 95 96gitlab="https://gitlab.com/kicad" 97# append commit hash or tag 98src_pre="https://gitlab.com/api/v4/projects/kicad%2Fcode%2Fkicad/repository/archive.tar.gz?sha=" 99lib_pre="https://gitlab.com/api/v4/projects/kicad%2Flibraries%2Fkicad-" 100lib_mid="/repository/archive.tar.gz?sha=" 101 102# number of items updated 103count=0 104 105printf "Latest tag is %s\n" "${latest_tag}" >&2 106 107if [[ ! -f ${file} ]]; then 108 echo "No existing file, generating from scratch" >&2 109 check_stable=1; check_testing=1; check_unstable=1; clean=1 110fi 111 112printf "Writing %s\n" "${tmp}" >&2 113 114# not a dangling brace, grouping the output to redirect to file 115{ 116 117printf "# This file was generated by update.sh\n\n" 118printf "{\n" 119 120for version in "${all_versions[@]}"; do 121 122 src_version=${version}; 123 lib_version=${version}; 124 # testing is the stable branch on the main repo 125 # but the libraries don't have such a branch 126 # only the latest release tag and a master branch 127 if [[ ${version} == "testing" ]]; then 128 src_version=${testing_branch}; 129 lib_version=${latest_tag}; 130 fi 131 132 if [[ ${version} == "master" ]]; then 133 pname="kicad-unstable" 134 elif [[ ${version} == "testing" ]]; then 135 pname="kicad-testing" 136 else 137 pname="kicad" 138 fi 139 140 # skip a version if we don't want to check it 141 if [[ (-n ${check_stable} && ${version} != "master" && ${version} != "testing") \ 142 || (-n ${check_testing} && ${version} == "testing") \ 143 || (-n ${check_unstable} && ${version} == "master" ) ]]; then 144 145 now=$(commit_date "${src_version}") 146 147 if [[ ${version} == "master" ]]; then 148 pname="kicad-unstable" 149 new_version="${now}" 150 elif [[ ${version} == "testing" ]]; then 151 pname="kicad-testing" 152 new_version="${testing_branch}-${now}" 153 else 154 pname="kicad" 155 new_version="${version}" 156 fi 157 158 printf "\nChecking %s\n" "${pname}" >&2 159 160 printf "%2s\"%s\" = {\n" "" "${pname}" 161 printf "%4skicadVersion = {\n" "" 162 printf "%6sversion =\t\t\t\"%s\";\n" "" "${new_version}" 163 printf "%6ssrc = {\n" "" 164 165 echo "Checking src" >&2 166 scratch="$(get_rev "${gitlab}"/code/kicad.git "${src_version}")" 167 src_rev="$(cut -f1 <<< "${scratch}")" 168 has_rev="$(grep -sm 1 "\"${pname}\"" -A 4 "${file}" | grep -sm 1 "${src_rev}" || true)" 169 has_hash="$(grep -sm 1 "\"${pname}\"" -A 5 "${file}" | grep -sm 1 "sha256" || true)" 170 old_version="$(grep -sm 1 "\"${pname}\"" -A 3 "${file}" | grep -sm 1 "version" | awk -F "\"" '{print $2}' || true)" 171 172 if [[ -n ${has_rev} && -n ${has_hash} && -z ${clean} ]]; then 173 echo "Reusing old ${pname}.src.sha256, already latest .rev at ${old_version}" >&2 174 scratch=$(grep -sm 1 "\"${pname}\"" -A 5 "${file}") 175 grep -sm 1 "rev" -A 1 <<< "${scratch}" 176 else 177 prefetched="$(${prefetch} "${src_pre}${src_rev}")" 178 printf "%8srev =\t\t\t\"%s\";\n" "" "${src_rev}" 179 printf "%8ssha256 =\t\t\"%s\";\n" "" "${prefetched}" 180 count=$((count+1)) 181 fi 182 printf "%6s};\n" "" 183 printf "%4s};\n" "" 184 185 printf "%4slibVersion = {\n" "" 186 printf "%6sversion =\t\t\t\"%s\";\n" "" "${new_version}" 187 printf "%6slibSources = {\n" "" 188 189 for lib in "${libs[@]}"; do 190 echo "Checking ${lib}" >&2 191 url="${gitlab}/libraries/kicad-${lib}.git" 192 scratch="$(get_rev "${url}" "${lib_version}")" 193 scratch="$(cut -f1 <<< "${scratch}")" 194 lib_rev="$(tail -n1 <<< "${scratch}")" 195 has_rev="$(grep -sm 1 "\"${pname}\"" -A 19 "${file}" | grep -sm 1 "${lib_rev}" || true)" 196 has_hash="$(grep -sm 1 "\"${pname}\"" -A 20 "${file}" | grep -sm 1 "${lib}.sha256" || true)" 197 if [[ -n ${has_rev} && -n ${has_hash} && -z ${clean} ]]; then 198 echo "Reusing old kicad-${lib}-${new_version}.src.sha256, already latest .rev" >&2 199 scratch="$(grep -sm 1 "\"${pname}\"" -A 20 "${file}")" 200 grep -sm 1 "${lib}" -A 1 <<< "${scratch}" 201 else 202 prefetched="$(${prefetch} "${lib_pre}${lib}${lib_mid}${lib_rev}")" 203 printf "%8s%s.rev =\t" "" "${lib}" 204 case "${lib}" in 205 symbols|templates) printf "\t" ;; *) ;; 206 esac 207 printf "\"%s\";\n" "${lib_rev}" 208 printf "%8s%s.sha256 =\t\"%s\";\n" "" "${lib}" "${prefetched}" 209 count=$((count+1)) 210 fi 211 done 212 printf "%6s};\n" "" 213 printf "%4s};\n" "" 214 printf "%2s};\n" "" 215 else 216 printf "\nReusing old %s\n" "${pname}" >&2 217 grep -sm 1 "\"${pname}\"" -A 21 "${file}" 218 fi 219done 220printf "}\n" 221} > "${tmp}" 222 223if grep '""' "${tmp}"; then 224 echo "empty value detected, out of space?" >&2 225 exit "1" 226fi 227 228mv "${tmp}" "${file}" 229 230printf "\nFinished\nMoved output to %s\n\n" "${file}" >&2 231 232if [[ ${count} -gt 0 ]]; then 233 if [[ ${count} -gt 1 ]]; then s="s"; else s=""; fi 234 echo "${count} revision${s} changed" >&2 235 if [[ -n ${commit} ]]; then 236 git commit -am "$(printf "kicad: automatic update of %s item%s\n" "${count}" "${s}")" 237 fi 238 echo "Please confirm the new versions.nix works before making a PR." >&2 239else 240 echo "No changes, those checked are up to date" >&2 241fi 242 243# using UPDATE_NIX_ATTR_PATH to detect if this is being called from update.nix 244# and output JSON to describe the changes 245if [[ -n ${UPDATE_NIX_ATTR_PATH} ]]; then 246 247 if [[ ${count} -eq 0 ]]; then echo "[{}]"; exit 0; fi 248 249 jq -n \ 250 --arg attrpath "${UPDATE_NIX_PNAME}" \ 251 --arg oldversion "${old_version}" \ 252 --arg newversion "${new_version}" \ 253 --arg file "${file}" \ 254'[{ 255 "attrPath": $attrpath, 256 "oldVersion": $oldversion, 257 "newVersion": $newversion, 258 "files": [ $file ] 259}]' 260fi