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 |