diff options
author | Horodniceanu Andrei <a.horodniceanu@protonmail.com> | 2023-07-22 21:45:47 +0300 |
---|---|---|
committer | Horodniceanu Andrei <a.horodniceanu@protonmail.com> | 2023-08-24 18:19:47 +0300 |
commit | 9460651c8b18809b99b13e5015fbbb302637d8fa (patch) | |
tree | f49049f910ecdae42103ed62fa1d1621614bd6ba /scripts | |
parent | Merge branch 'onedrivegui' (diff) | |
download | dlang-9460651c8b18809b99b13e5015fbbb302637d8fa.tar.gz dlang-9460651c8b18809b99b13e5015fbbb302637d8fa.tar.bz2 dlang-9460651c8b18809b99b13e5015fbbb302637d8fa.zip |
scripts: Add update-gdc-versions.sh
Signed-off-by: Horodniceanu Andrei <a.horodniceanu@protonmail.com>
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/update-gdc-versions.sh | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/scripts/update-gdc-versions.sh b/scripts/update-gdc-versions.sh new file mode 100755 index 0000000..4b0050f --- /dev/null +++ b/scripts/update-gdc-versions.sh @@ -0,0 +1,279 @@ +#!/bin/bash +# Copyright 2023 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +# This script uses various utilities from app-portage/portage-utils + +# No -u because /lib/gentoo/functions.sh doesn't work with it +set -eo pipefail +shopt -s nullglob + +source /lib/gentoo/functions.sh + +REPO="$(dirname "${0}")" +cd "${REPO}/.." +readonly EROOT=$(portageq envvar EROOT) +readonly PORTDIR=$(portageq get_repo_path "${EROOT}" gentoo) + +# Associative array betwen gcc $PVRs and their keywords +declare -A GCC_TO_KEYWORDS +# Associative array between gcc slots (gdmd versions) and a combination +# of the keywords of each gcc version is said slot. +declare -A SLOT_TO_KEYWORDS +# Program to use for running privileged commands. +# The user may specify this manually, or it will be autodetected. +declare SUDO + +die () { + eerror "${@}" + exit 1 +} + +keyword_to_arch () { + [[ $# -ne 1 ]] && die "Internal error: Passed $# arguments to ${FUNCNAME}" + + if [[ ${1:0:1} == @(-|~) ]]; then + echo "${1:1}" + else + echo "${1}" + fi +} + +keyword_to_stability () { + [[ $# -ne 1 ]] && die "Internal error: Passed $# arguments to ${FUNCNAME}" + + if [[ ${1:0:1} = '-' ]]; then + echo 0 + elif [[ ${1:0:1} = '~' ]]; then + echo 1 + else + echo 2 + fi +} + +# Combines 2 keywords for the same arch so that the more stable one is chosen +# amd64 - stable +# ~amd64 - unstable +# -amd64 - disabled +combine_arch_keywords () { + [[ $# -ne 2 ]] && die "Internal error: Passed $# arguments to ${FUNCNAME}" + local k1="${1}" k2="${2}" + [[ $(keyword_to_arch $k1) != $(keyword_to_arch $k2) ]] && \ + die "Internal error: ${FUNCNAME} got keywords for difference arches" + + + local s1=$(keyword_to_stability "${k1}") + local s2=$(keyword_to_stability "${k2}") + + if [[ $s1 -ge $s2 ]]; then + echo "${k1}" + else + echo "${k2}" + fi +} + +# Given 2 list of keywords returns a new list with the most stable keywords taken +# from both lists +combine_keywords () { + [[ $# -ne 2 ]] && die "Internal error: Passed $# arguments to ${FUNCNAME}" + local v1=($1) v2=($2) # We want the expansion + + # We take advantage that the keyword arrays are sorted + local n=${#v1[@]} m=${#v2[@]} + local i=0 j=0 + + local result=() + + while (( i < n && j < m )); do + local a1=$(keyword_to_arch "${v1[$i]}") + local a2=$(keyword_to_arch "${v2[$j]}") + + if [[ $a1 = $a2 ]]; then + result+=("$(combine_arch_keywords "${v1[$i]}" "${v2[$j]}")") + ((++i, ++j)) || true + elif [[ $a1 < $a2 ]]; then + result+=("${v1[$i]}") + ((++i)) || true + else + result+=("${v2[$j]}") + ((++j)) || true + fi + done + + result+=("${v1[@]:$i}") + result+=("${v2[@]:$j}") + + echo "${result[@]}" +} + +# Check if there is an ebuild of gdmd for a specific version of gcc. +# $1 can either be a gcc slot of a gcc version, they are both calculated +# in the same way. +can_handle () { + [[ $# -ne 1 ]] && die "Internal error: Passed $# arguments to ${FUNCNAME}" + + local slot="${1%%\.*}" + + [[ -f "dev-util/gdmd/gdmd-${slot}.ebuild" ]] +} + +# Run a privileged command +asroot () { + [[ $# -eq 0 ]] && die "Internal error: Didn't pass any arguments to ${FUNCNAME}" + if [[ ${EUID} -ne 0 && -z ${SUDO} ]]; then + # Check for either sudo or doas in PATH + if type -P sudo > /dev/null; then + SUDO=sudo + elif type -P doas > /dev/null; then + SUDO=doas + else + die "Didn't find any command for privilege escalation" + fi + fi + + echo "Running: ${SUDO} ${@}" + # Let $SUDO be shell expanded in case it is empty + ${SUDO} "${@}" +} + +while read -r keywords; do + filename="${keywords%:*}" + keywords="${keywords#*KEYWORDS=\"}" + keywords="${keywords%\"}" + + version="$(qatom -F'%{PVR}' "${filename}")" + + if [[ $version =~ .*9999.* ]]; then + # Don't include live ebuilds + continue + fi + + # Filter out hppa and sparc keywords + keyarr=(${keywords}) + for (( i=0; i<"${#keyarr[@]}"; ++i)); do + [[ $(keyword_to_arch "${keyarr[$i]}") == @(hppa|sparc) ]] && unset "keyarr[$i]" + done + keywords="${keyarr[@]}" + + quse -ep "sys-devel/gcc-${version}" | egrep -wq '[+-]?d' && \ + GCC_TO_KEYWORDS[${version}]="${keywords}" + +done < <(egrep "^\s*KEYWORDS" "${PORTDIR}/sys-devel/gcc/gcc"*) + +for version in "${!GCC_TO_KEYWORDS[@]}"; do + slot="${version%%\.*}" + + if [[ ! -v SLOT_TO_KEYWORDS[${slot}] ]]; then + SLOT_TO_KEYWORDS[${slot}]="${GCC_TO_KEYWORDS[${version}]}" + else + SLOT_TO_KEYWORDS[${slot}]=$(combine_keywords \ + "${SLOT_TO_KEYWORDS[${slot}]}" \ + "${GCC_TO_KEYWORDS[${version}]}") + fi +done + +###### Modify keywords for each gdmd ebuild ####### +for slot in "${!SLOT_TO_KEYWORDS[@]}"; do + if ! can_handle "${slot}"; then continue; fi + + file="dev-util/gdmd/gdmd-${slot}.ebuild" + sed -i -e 's/^KEYWORDS=.*$/KEYWORDS="'"${SLOT_TO_KEYWORDS[$slot]}"'"/' "${file}" +done + +##### Calculate gdc frontends ##### +declare -a GDC_TARGETS +for version in "${!GCC_TO_KEYWORDS[@]}"; do + if ! can_handle "${version}"; then continue; fi + # For a gdc USE flag, we need only the package version (i.e. no -r* sufix) + pv="${version%-r*}" + + ebuild="${PORTDIR}/sys-devel/gcc/gcc-${version}.ebuild" + asroot ebuild "${ebuild}" unpack + + prefix="$(portageq envvar PORTAGE_TMPDIR)/portage/sys-devel/gcc-${version}" + + # Make /var/tmp/portage/sys-devel/gcc* traversable for the normal user + # to prevent asking for the root password for each file we want to check. + asroot chmod +rx "${prefix}" "${prefix}/work" + + # I don't know how to expand the string properly, without bash quiting due to the error of not finding the path + path=$(echo "${prefix}/work/gcc-"*/gcc/d/dmd/VERSION) + + if [[ -f ${path} ]]; then + dmdVersion=$(cat "${path}") + # The version in $path looks like: v2.100.1 or v2.103.0-rc.1 + dmdVersion=${dmdVersion#v} + dmdVersion=${dmdVersion%-*} # In case there's a -rc.x component + dmdVersion=${dmdVersion%.*} + else + # This one is always present + merge_file=$(echo "${prefix}/work/gcc-"*/gcc/d/dmd/MERGE) + [[ ! -f ${merge_file} ]] && die "Can not access '${merge_file}'" + if [[ $(head -n1 ${merge_file}) = "0450061c8de71328815da9323bd35c92b37d51d2" ]]; then + # A common commit id with dmd version 2.076 + dmdVersion="2.076" + else + dmdVersion="<CHANGEME>" + fi + fi + + # For the format of an element look in eclass/dlang-compilers.eclass. + + # Don't add the [" that should be at the beggining of an element + # because we will need to sort the array and `sort -n` doesn't like + # the leading non-numerical characters. + # We will add [" later. + GDC_TARGETS+=("${pv}\"]=\"${dmdVersion} ${GCC_TO_KEYWORDS[$version]}\"") + + asroot ebuild "${ebuild}" clean +done + +# Sort the GDC_TARGETS array +IFS=$'\n' GDC_TARGETS=($(sort -n <<<"${GDC_TARGETS[*]}")) +unset IFS + +perl -0777 -i -wpe \ + 's{ + (_dlang_gdc_frontend=\() # prefix of the lines we want to change, capturing + (?:.*?) # Everything in-between until a paranthesis, non greedy, non capturing + (\n\s*\)) # Capture the end paranthesis `\)`, include the newline and the spacing + }{$1'"$(printf '\n\t\t["%s' "${GDC_TARGETS[@]}")"'$2}xs' \ + eclass/dlang-compilers.eclass + # x - ignore comments in the regex, and whitespaces + # s - allow . to match \n + # replace all the lines in between $1 `_dlang_gdc_frontend(` + # and $2 `)` with the elements of ${GDC_TARGETS[@]}, separated by \n and \t\t. + # The first element also gets this delimiter, hence we don't capture the \n + # in the first group but we do in the last group. + # We also add back the [" we trimed before + +##### Add the USE flag descriptions ##### +declare -a GDC_DESCRIPTIONS +for version in "${!GCC_TO_KEYWORDS[@]}"; do + if ! can_handle "${version}"; then continue; fi + # $version may look like: 11.3.1_p20221209, 11.4.0, 10.3.1_p20230426-r1 + # we need use.desc to contain: + # gdc-11_3_1_p20231209 - Build for GCC 11.3.1_p20221209 + # gdc-11_4_0 - Build for GCC 11.4.0 + # gdc-10_3_1_p20230426 - Build for GCC 10.3.1_p20230426 + + pv="${version%-r*}" + + # For each line add the text starting from the version (remove 'gdc-') + # to be able to sort the entries properly after. + gdc="${pv//./_}" + gcc="${pv}" + GDC_DESCRIPTIONS+=("${gdc} - Build for GCC ${gcc}") +done + +# Sort the descriptions +IFS=$'\n' GDC_DESCRIPTIONS=($(sort -n <<<"${GDC_DESCRIPTIONS[*]}")) +unset IFS + +perl -0777 -i -wpe \ + 's{ + (?:^gdc.*\n)+ # we change all the lines that starts with gdc + # We need the multiline mode (m) below to make ^ match and embeded new lines + }{'"$(printf 'gdc-%s\n' "${GDC_DESCRIPTIONS[@]}")"'\n}xm' profiles/use.desc + +exit 0 |