Gentoo Archives: gentoo-dev

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

Replies