diff options
author | V3n3RiX <venerix@redcorelinux.org> | 2020-11-25 22:39:15 +0000 |
---|---|---|
committer | V3n3RiX <venerix@redcorelinux.org> | 2020-11-25 22:39:15 +0000 |
commit | d934827bf44b7cfcf6711964418148fa60877668 (patch) | |
tree | 0625f358789b5e015e49db139cc1dbc9be00428f /eclass/eapi8-dosym.eclass | |
parent | 2e34d110f164bf74d55fced27fe0000201b3eec5 (diff) |
gentoo resync : 25.11.2020
Diffstat (limited to 'eclass/eapi8-dosym.eclass')
-rw-r--r-- | eclass/eapi8-dosym.eclass | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/eclass/eapi8-dosym.eclass b/eclass/eapi8-dosym.eclass new file mode 100644 index 000000000000..52f0ffe3e62b --- /dev/null +++ b/eclass/eapi8-dosym.eclass @@ -0,0 +1,108 @@ +# Copyright 2020 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: eapi8-dosym.eclass +# @MAINTAINER: +# PMS team <pms@gentoo.org> +# @AUTHOR: +# Ulrich Müller <ulm@gentoo.org> +# @SUPPORTED_EAPIS: 5 6 7 +# @BLURB: Testing implementation of EAPI 8 dosym -r option +# @DESCRIPTION: +# A stand-alone implementation of the dosym command aimed for EAPI 8. +# Intended to be used for wider testing of the proposed option and to +# allow ebuilds to switch to the new model early, with minimal change +# needed for actual EAPI 8. +# +# https://bugs.gentoo.org/708360 + +case ${EAPI} in + 5|6|7) ;; + *) die "${ECLASS}: EAPI=${EAPI:-0} not supported" ;; +esac + +# @FUNCTION: _dosym8_canonicalize +# @USAGE: <path> +# @INTERNAL +# @DESCRIPTION: +# Transparent bash-only replacement for GNU "realpath -m -s". +# Resolve references to "/./", "/../" and remove extra "/" characters +# from <path>, without touching any actual file. +_dosym8_canonicalize() { + local path slash i prev out IFS=/ + + path=( $1 ) + [[ $1 == /* ]] && slash=/ + + while true; do + # Find first instance of non-".." path component followed by "..", + # or as a special case, "/.." at the beginning of the path. + # Also drop empty and "." path components as we go along. + prev= + for i in ${!path[@]}; do + if [[ -z ${path[i]} || ${path[i]} == . ]]; then + unset "path[i]" + elif [[ ${path[i]} != .. ]]; then + prev=${i} + elif [[ ${prev} || ${slash} ]]; then + # Found, remove path components and reiterate + [[ ${prev} ]] && unset "path[prev]" + unset "path[i]" + continue 2 + fi + done + # No (further) instance found, so we're done + break + done + + out="${slash}${path[*]}" + echo "${out:-.}" +} + +# @FUNCTION: dosym8 +# @USAGE: [-r] <target> <link> +# @DESCRIPTION: +# Create a symbolic link <link>, pointing to <target>. If the +# directory containing the new link does not exist, create it. +# +# If called with option -r, expand <target> relative to the apparent +# path of the directory containing <link>. For example, "dosym8 -r +# /bin/foo /usr/bin/foo" will create a link named "../../bin/foo". +dosym8() { + local option_r + + case $1 in + -r) option_r=t; shift ;; + esac + + [[ $# -eq 2 ]] || die "${FUNCNAME}: bad number of arguments" + + local target=$1 link=$2 + + if [[ ${option_r} ]]; then + local linkdir comp + + # Expansion makes sense only for an absolute target path + [[ ${target} == /* ]] \ + || die "${FUNCNAME}: -r specified but no absolute target path" + + target=$(_dosym8_canonicalize "${target}") + linkdir=$(_dosym8_canonicalize "/${link#/}") + linkdir=${linkdir%/*} # poor man's dirname(1) + linkdir=${linkdir:-/} # always keep the initial "/" + + local ifs_save=${IFS-$' \t\n'} IFS=/ + for comp in ${linkdir}; do + if [[ ${target%%/*} == "${comp}" ]]; then + target=${target#"${comp}"} + target=${target#/} + else + target=..${target:+/}${target} + fi + done + IFS=${ifs_save} + target=${target:-.} + fi + + dosym "${target}" "${link}" +} |