commit:     8468c732604cf2a0827c0025534173f4276b05f6
Author:     Horodniceanu Andrei <a.horodniceanu <AT> proton <DOT> me>
AuthorDate: Tue Oct 17 06:47:24 2023 +0000
Commit:     Horodniceanu Andrei <a.horodniceanu <AT> proton <DOT> me>
CommitDate: Sun Oct 29 10:59:45 2023 +0000
URL:        https://gitweb.gentoo.org/repo/user/dlang.git/commit/?id=8468c732

scripts: update-gdc-versions.sh support gdc-SLOT USE flags

Other changes:
- added an usage header
- option -a can be used to test all relevant gcc ebuilds
- fixed typoes

Closes: https://github.com/gentoo/dlang/pull/126
Signed-off-by: Horodniceanu Andrei <a.horodniceanu <AT> proton.me>

 scripts/update-gdc-versions.sh | 205 ++++++++++++++++++++++++++---------------
 1 file changed, 131 insertions(+), 74 deletions(-)

diff --git a/scripts/update-gdc-versions.sh b/scripts/update-gdc-versions.sh
index 4b0050f..e3a33b4 100755
--- a/scripts/update-gdc-versions.sh
+++ b/scripts/update-gdc-versions.sh
@@ -2,6 +2,26 @@
 # Copyright 2023 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
+###### Usage ######
+# ./update-gdc-versions.sh [-a]
+#
+# Update all gdc related variables in this overlay:
+# 1. gdmd keywords
+# 2. dlang-compilers.eclass
+# 3. use.desc
+# based on the gcc versions currently available in ::gentoo.
+#
+# You will be prompted for you sudo/doas password at the end to
+# extract the dmd version from the gcc sources because the ebuild
+# command requires elevated privileges. Alternatively you may run this
+# script as root.
+#
+# By default, only 1 gcc version for each gdmd slot needs to be
+# extracted. Otherwise, when the -a option is passed, force check of
+# (almost) all gcc ebuilds. This will prompt for your sudo/doas password
+# more so it may be worth to run the script as root in this case.
+###### End Usage ######
+
 # This script uses various utilities from app-portage/portage-utils
 
 # No -u because /lib/gentoo/functions.sh doesn't work with it
@@ -14,11 +34,12 @@ REPO="$(dirname "${0}")"
 cd "${REPO}/.."
 readonly EROOT=$(portageq envvar EROOT)
 readonly PORTDIR=$(portageq get_repo_path "${EROOT}" gentoo)
+[[ ${1} == "-a" ]] && readonly CHECK_ALL=1 || readonly CHECK_ALL=0
 
 # 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.
+# of the keywords of each gcc version in 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.
@@ -40,7 +61,7 @@ keyword_to_arch () {
 }
 
 keyword_to_stability () {
-       [[ $# -ne 1 ]] && die "Internal error: Passed $# arguments to 
${FUNCNAME}"
+       [[ $# -ne 1 ]] && die "Internal error: Passed $# arguments to 
${FUNCNAME}, expected 1"
 
        if [[ ${1:0:1} = '-' ]]; then
                echo 0
@@ -56,7 +77,7 @@ keyword_to_stability () {
 # ~amd64 - unstable
 # -amd64 - disabled
 combine_arch_keywords () {
-       [[ $# -ne 2 ]] && die "Internal error: Passed $# arguments to 
${FUNCNAME}"
+       [[ $# -ne 2 ]] && die "Internal error: Passed $# arguments to 
${FUNCNAME}, expected 2"
        local k1="${1}" k2="${2}"
        [[ $(keyword_to_arch $k1) != $(keyword_to_arch $k2) ]] && \
                die "Internal error: ${FUNCNAME} got keywords for difference 
arches"
@@ -75,7 +96,7 @@ combine_arch_keywords () {
 # 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}"
+       [[ $# -ne 2 ]] && die "Internal error: Passed $# arguments to 
${FUNCNAME}, exptected 2"
        local v1=($1) v2=($2) # We want the expansion
 
        # We take advantage that the keyword arrays are sorted
@@ -85,23 +106,23 @@ combine_keywords () {
        local result=()
 
        while (( i < n && j < m )); do
-               local a1=$(keyword_to_arch "${v1[$i]}")
-               local a2=$(keyword_to_arch "${v2[$j]}")
+               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]}")")
+                       result+=("$(combine_arch_keywords "${v1[i]}" 
"${v2[j]}")")
                        ((++i, ++j)) || true
                elif [[ $a1 < $a2 ]]; then
-                       result+=("${v1[$i]}")
+                       result+=("${v1[i]}")
                        ((++i)) || true
                else
-                       result+=("${v2[$j]}")
+                       result+=("${v2[j]}")
                        ((++j)) || true
                fi
        done
 
-       result+=("${v1[@]:$i}")
-       result+=("${v2[@]:$j}")
+       result+=("${v1[@]:i}")
+       result+=("${v2[@]:j}")
 
        echo "${result[@]}"
 }
@@ -110,7 +131,7 @@ combine_keywords () {
 # $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}"
+       [[ $# -ne 1 ]] && die "Internal error: Passed $# arguments to 
${FUNCNAME}, exptected 1"
 
        local slot="${1%%\.*}"
 
@@ -136,6 +157,48 @@ asroot () {
        ${SUDO} "${@}"
 }
 
+# Get the dmd version from a gcc PVR
+get_gcc_dmd_version () {
+       [[ $# -ne 1 ]] && die "Internal error: Passed $# arguments to 
${FUNCNAME}, expected 1"
+       version="${1}"
+
+       ebuild="${PORTDIR}/sys-devel/gcc/gcc-${version}.ebuild"
+       # Pass the ebuild output on stderr
+       asroot ebuild "${ebuild}" unpack >&2
+
+       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" >&2
+
+       # I don't know another way to explicitly expand the *
+       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
+
+       asroot ebuild "${ebuild}" clean >&2
+
+       echo "${dmdVersion}"
+}
+
+# Find the keywords for each gcc ebuild (that support d)
 while read -r keywords; do
        filename="${keywords%:*}"
        keywords="${keywords#*KEYWORDS=\"}"
@@ -160,6 +223,7 @@ while read -r keywords; do
 
 done < <(egrep "^\s*KEYWORDS" "${PORTDIR}/sys-devel/gcc/gcc"*)
 
+# Merge all the KEYWORDS in a slot into a single list
 for version in "${!GCC_TO_KEYWORDS[@]}"; do
        slot="${version%%\.*}"
 
@@ -172,62 +236,65 @@ for version in "${!GCC_TO_KEYWORDS[@]}"; do
        fi
 done
 
-###### Modify keywords for each gdmd ebuild #######
+###### Modify keywords for each gdmd ebuild and gdc USE flags #######
+declare -a GDC_TARGETS
 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"
+       if [[ ${CHECK_ALL} == 0 ]]; then
+               atom="$(portageq best_visible "${EROOT}" 
"sys-devel/gcc:${slot}")"
+               version="${atom##*-}"
 
-       # 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)
+               dmdVersion="$(get_gcc_dmd_version "${version}")"
+               [[ -z ${dmdVersion} ]] && dmdVersion="<CHANGEME>"
 
-       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%.*}
+               # We skip adding the [" that should be at the begining so we
+               # can properly sort the array later.
+               GDC_TARGETS+=("${slot}\"]=\"${dmdVersion} 
${SLOT_TO_KEYWORDS[${slot}]}\"")
        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
+               # Avoid multiple extractions for the same ebuild.
+               # Let the code below generate the targets
+               :
        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
 
+###### Verify all gcc ebuilds ######
+if [[ ${CHECK_ALL} == 1 ]]; then
+       # Theoretically, we only need to check 1 version for each slot but,
+       # for safety, check them all and see if all versions in 1 slot
+       # have the same dmd version.
+       declare -A SLOT_TO_DMD_VERSIONS
+       for version in "${!GCC_TO_KEYWORDS[@]}"; do
+               if ! can_handle "${version}"; then continue; fi
+               slot="${version%%\.*}"
+               dmdVersion="$(get_gcc_dmd_version "${version}")"
+
+               if [[ ! -v SLOT_TO_DMD_VERSIONS[${slot}] ]]; then
+                       # First time seeing a version for $slot, not much to 
check.
+                       SLOT_TO_DMD_VERSIONS[${slot}]="${dmdVersion}"
+
+                       # Don't forget that we also have to generate 
GDC_TARGETS.
+                       if can_handle "${slot}"; then
+                               # Same notes as above.
+                               GDC_TARGETS+=("${slot}\"]=\"${dmdVersion} 
${SLOT_TO_KEYWORDS[${slot}]}\"")
+                       fi
+               else
+                       # We know what dmdVersion should be for a slot.
+                       if [[ ${SLOT_TO_DMD_VERSIONS[${slot}]} != ${dmdVersion} 
]]; then
+                               eerror "Found multiple dmd versions in the same 
slot ${slot}."
+                               eerror "Did gcc's policies change?"
+                               die "Assumptions by this script about gcc slots 
were not met"
+                       else
+                               # All good :)
+                               :
+                       fi
+               fi
+       done
+fi
+
 # Sort the GDC_TARGETS array
 IFS=$'\n' GDC_TARGETS=($(sort -n <<<"${GDC_TARGETS[*]}"))
 unset IFS
@@ -249,21 +316,12 @@ perl -0777 -i -wpe \
 
 ##### 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}")
+for slot in "${!SLOT_TO_KEYWORDS[@]}"; do
+       if ! can_handle "${slot}"; then continue; fi
+       # slot is a simple number: 11, 12, 13 etc.
+
+       # Same as for the other array, we wil add the prefix 'gdc-' later.
+       GDC_DESCRIPTIONS+=("${slot} - Build for GCC ${slot}")
 done
 
 # Sort the descriptions
@@ -272,8 +330,7 @@ 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
+        (?:^gdc.*\n)+ # we change all the lines that start with gdc
+        # We need the multiline mode (m) below to make ^ match at embeded new 
lines
         }{'"$(printf 'gdc-%s\n' "${GDC_DESCRIPTIONS[@]}")"'\n}xm' 
profiles/use.desc
 
-exit 0

Reply via email to