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