Gentoo Archives: gentoo-dev

From: "Ulrich Müller" <ulm@g.o>
To: gentoo-dev@l.g.o
Cc: "Ulrich Müller" <ulm@g.o>
Subject: [gentoo-dev] [PATCH 1/2] eapi8-dosym.eclass: New eclass.
Date: Thu, 19 Nov 2020 10:32:43
Message-Id: 20201119103150.22841-1-ulm@gentoo.org
1 This implements the dosym command proposed for EAPI 8 (called dosym8
2 because we cannot use the same name as the package-manager builtin).
3
4 "dosym -r <target> <link>" will expand the (apparent) path of <target>
5 relative to the (apparent) path of the directory containing <link>.
6 The main aim of this is to allow for an absolute path to be specified
7 as the link target, and the function will count path components and
8 convert it into a relative path.
9
10 Since we're inside ED at this point but the image will finally be
11 installed in EROOT, we don't try to resolve any pre-existing symlinks
12 in <target> or <link>. In other words, path expansion only looks at
13 the specified apparent paths, without touching any actual files in ED
14 or EROOT.
15
16 Signed-off-by: Ulrich Müller <ulm@g.o>
17 ---
18 eclass/eapi8-dosym.eclass | 108 ++++++++++++++++++++++++++++++++++++++
19 1 file changed, 108 insertions(+)
20 create mode 100644 eclass/eapi8-dosym.eclass
21
22 diff --git a/eclass/eapi8-dosym.eclass b/eclass/eapi8-dosym.eclass
23 new file mode 100644
24 index 000000000000..52f0ffe3e62b
25 --- /dev/null
26 +++ b/eclass/eapi8-dosym.eclass
27 @@ -0,0 +1,108 @@
28 +# Copyright 2020 Gentoo Authors
29 +# Distributed under the terms of the GNU General Public License v2
30 +
31 +# @ECLASS: eapi8-dosym.eclass
32 +# @MAINTAINER:
33 +# PMS team <pms@g.o>
34 +# @AUTHOR:
35 +# Ulrich Müller <ulm@g.o>
36 +# @SUPPORTED_EAPIS: 5 6 7
37 +# @BLURB: Testing implementation of EAPI 8 dosym -r option
38 +# @DESCRIPTION:
39 +# A stand-alone implementation of the dosym command aimed for EAPI 8.
40 +# Intended to be used for wider testing of the proposed option and to
41 +# allow ebuilds to switch to the new model early, with minimal change
42 +# needed for actual EAPI 8.
43 +#
44 +# https://bugs.gentoo.org/708360
45 +
46 +case ${EAPI} in
47 + 5|6|7) ;;
48 + *) die "${ECLASS}: EAPI=${EAPI:-0} not supported" ;;
49 +esac
50 +
51 +# @FUNCTION: _dosym8_canonicalize
52 +# @USAGE: <path>
53 +# @INTERNAL
54 +# @DESCRIPTION:
55 +# Transparent bash-only replacement for GNU "realpath -m -s".
56 +# Resolve references to "/./", "/../" and remove extra "/" characters
57 +# from <path>, without touching any actual file.
58 +_dosym8_canonicalize() {
59 + local path slash i prev out IFS=/
60 +
61 + path=( $1 )
62 + [[ $1 == /* ]] && slash=/
63 +
64 + while true; do
65 + # Find first instance of non-".." path component followed by "..",
66 + # or as a special case, "/.." at the beginning of the path.
67 + # Also drop empty and "." path components as we go along.
68 + prev=
69 + for i in ${!path[@]}; do
70 + if [[ -z ${path[i]} || ${path[i]} == . ]]; then
71 + unset "path[i]"
72 + elif [[ ${path[i]} != .. ]]; then
73 + prev=${i}
74 + elif [[ ${prev} || ${slash} ]]; then
75 + # Found, remove path components and reiterate
76 + [[ ${prev} ]] && unset "path[prev]"
77 + unset "path[i]"
78 + continue 2
79 + fi
80 + done
81 + # No (further) instance found, so we're done
82 + break
83 + done
84 +
85 + out="${slash}${path[*]}"
86 + echo "${out:-.}"
87 +}
88 +
89 +# @FUNCTION: dosym8
90 +# @USAGE: [-r] <target> <link>
91 +# @DESCRIPTION:
92 +# Create a symbolic link <link>, pointing to <target>. If the
93 +# directory containing the new link does not exist, create it.
94 +#
95 +# If called with option -r, expand <target> relative to the apparent
96 +# path of the directory containing <link>. For example, "dosym8 -r
97 +# /bin/foo /usr/bin/foo" will create a link named "../../bin/foo".
98 +dosym8() {
99 + local option_r
100 +
101 + case $1 in
102 + -r) option_r=t; shift ;;
103 + esac
104 +
105 + [[ $# -eq 2 ]] || die "${FUNCNAME}: bad number of arguments"
106 +
107 + local target=$1 link=$2
108 +
109 + if [[ ${option_r} ]]; then
110 + local linkdir comp
111 +
112 + # Expansion makes sense only for an absolute target path
113 + [[ ${target} == /* ]] \
114 + || die "${FUNCNAME}: -r specified but no absolute target path"
115 +
116 + target=$(_dosym8_canonicalize "${target}")
117 + linkdir=$(_dosym8_canonicalize "/${link#/}")
118 + linkdir=${linkdir%/*} # poor man's dirname(1)
119 + linkdir=${linkdir:-/} # always keep the initial "/"
120 +
121 + local ifs_save=${IFS-$' \t\n'} IFS=/
122 + for comp in ${linkdir}; do
123 + if [[ ${target%%/*} == "${comp}" ]]; then
124 + target=${target#"${comp}"}
125 + target=${target#/}
126 + else
127 + target=..${target:+/}${target}
128 + fi
129 + done
130 + IFS=${ifs_save}
131 + target=${target:-.}
132 + fi
133 +
134 + dosym "${target}" "${link}"
135 +}
136 --
137 2.29.2

Replies