net-fs/openafs-kernel: remove vulnerable versions
[gentoo.git] / eclass / ghc-package.eclass
1 # Copyright 1999-2015 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Id$
4
5 # @ECLASS: ghc-package.eclass
6 # @MAINTAINER:
7 # "Gentoo's Haskell Language team" <haskell@gentoo.org>
8 # @AUTHOR:
9 # Original Author: Andres Loeh <kosmikus@gentoo.org>
10 # @BLURB: This eclass helps with the Glasgow Haskell Compiler's package configuration utility.
11 # @DESCRIPTION:
12 # Helper eclass to handle ghc installation/upgrade/deinstallation process.
13
14 inherit versionator
15
16 # @FUNCTION: ghc-getghc
17 # @DESCRIPTION:
18 # returns the name of the ghc executable
19 ghc-getghc() {
20         type -P ghc
21 }
22
23 # @FUNCTION: ghc-getghcpkg
24 # @DESCRIPTION:
25 # Internal function determines returns the name of the ghc-pkg executable
26 ghc-getghcpkg() {
27         type -P ghc-pkg
28 }
29
30 # @FUNCTION: ghc-getghcpkgbin
31 # @DESCRIPTION:
32 # returns the name of the ghc-pkg binary (ghc-pkg
33 # itself usually is a shell script, and we have to
34 # bypass the script under certain circumstances);
35 # for Cabal, we add an empty global package config file,
36 # because for some reason the global package file
37 # must be specified
38 ghc-getghcpkgbin() {
39         if version_is_at_least "7.9.20141222" "$(ghc-version)"; then
40                 # ghc-7.10 stopped supporting single-file database
41                 local empty_db="${T}/empty.conf.d" ghc_pkg="$(ghc-libdir)/bin/ghc-pkg"
42                 if [[ ! -d ${empty_db} ]]; then
43                         "${ghc_pkg}" init "${empty_db}" || die "Failed to initialize empty global db"
44                 fi
45                 echo "$(ghc-libdir)/bin/ghc-pkg" "--global-package-db=${empty_db}"
46
47         elif version_is_at_least "7.7.20121101" "$(ghc-version)"; then
48                 # the ghc-pkg executable changed name in ghc 6.10, as it no longer needs
49                 # the wrapper script with the static flags
50                 # was moved to bin/ subtree by:
51                 # http://www.haskell.org/pipermail/cvs-ghc/2012-September/076546.html
52                 echo '[]' > "${T}/empty.conf"
53                 echo "$(ghc-libdir)/bin/ghc-pkg" "--global-package-db=${T}/empty.conf"
54
55         elif version_is_at_least "7.5.20120516" "$(ghc-version)"; then
56                 echo '[]' > "${T}/empty.conf"
57                 echo "$(ghc-libdir)/ghc-pkg" "--global-package-db=${T}/empty.conf"
58
59         else
60                 echo '[]' > "${T}/empty.conf"
61                 echo "$(ghc-libdir)/ghc-pkg" "--global-conf=${T}/empty.conf"
62         fi
63 }
64
65 # @FUNCTION: ghc-version
66 # @DESCRIPTION:
67 # returns upstream version of ghc
68 # as reported by '--numeric-version'
69 # Examples: "7.10.2", "7.9.20141222"
70 _GHC_VERSION_CACHE=""
71 ghc-version() {
72         if [[ -z "${_GHC_VERSION_CACHE}" ]]; then
73                 _GHC_VERSION_CACHE="$($(ghc-getghc) --numeric-version)"
74         fi
75         echo "${_GHC_VERSION_CACHE}"
76 }
77
78 # @FUNCTION: ghc-pm-version
79 # @DESCRIPTION:
80 # returns package manager(PM) version of ghc
81 # as reported by '$(best_version)'
82 # Examples: "PM:7.10.2", "PM:7.10.2_rc1", "PM:7.8.4-r4"
83 _GHC_PM_VERSION_CACHE=""
84 ghc-pm-version() {
85         local pm_ghc_p
86
87         if [[ -z "${_GHC_PM_VERSION_CACHE}" ]]; then
88                 pm_ghc_p=$(best_version dev-lang/ghc)
89                 _GHC_PM_VERSION_CACHE="PM:${pm_ghc_p#dev-lang/ghc-}"
90         fi
91         echo "${_GHC_PM_VERSION_CACHE}"
92 }
93
94 # @FUNCTION: ghc-cabal-version
95 # @DESCRIPTION:
96 # return version of the Cabal library bundled with ghc
97 ghc-cabal-version() {
98         if version_is_at_least "7.9.20141222" "$(ghc-version)"; then
99                 # outputs in format: 'version: 1.18.1.5'
100                 set -- `$(ghc-getghcpkg) --package-db=$(ghc-libdir)/package.conf.d.initial field Cabal version`
101                 echo "$2"
102         else
103                 local cabal_package=`echo "$(ghc-libdir)"/Cabal-*`
104                 # /path/to/ghc/Cabal-${VER} -> ${VER}
105                 echo "${cabal_package/*Cabal-/}"
106         fi
107 }
108
109 # @FUNCTION: ghc-sanecabal
110 # @DESCRIPTION:
111 # check if a standalone Cabal version is available for the
112 # currently used ghc; takes minimal version of Cabal as
113 # an optional argument
114 ghc-sanecabal() {
115         local f
116         local version
117         if [[ -z "$1" ]]; then version="1.0.1"; else version="$1"; fi
118         for f in $(ghc-confdir)/cabal-*; do
119                 [[ -f "${f}" ]] && version_is_at_least "${version}" "${f#*cabal-}" && return
120         done
121         return 1
122 }
123 # @FUNCTION: ghc-is-dynamic
124 # @DESCRIPTION:
125 # checks if ghc is built against dynamic libraries
126 # binaries linked against GHC library (and using plugin loading)
127 # have to be linked the same way:
128 #    https://ghc.haskell.org/trac/ghc/ticket/10301
129 ghc-is-dynamic() {
130         $(ghc-getghc) --info | grep "GHC Dynamic" | grep -q "YES"
131 }
132
133 # @FUNCTION: ghc-supports-shared-libraries
134 # @DESCRIPTION:
135 # checks if ghc is built with support for building
136 # shared libraries (aka '-dynamic' option)
137 ghc-supports-shared-libraries() {
138         $(ghc-getghc) --info | grep "RTS ways" | grep -q "dyn"
139 }
140
141 # @FUNCTION: ghc-supports-threaded-runtime
142 # @DESCRIPTION:
143 # checks if ghc is built with support for threaded
144 # runtime (aka '-threaded' option)
145 ghc-supports-threaded-runtime() {
146         $(ghc-getghc) --info | grep "RTS ways" | grep -q "thr"
147 }
148
149 # @FUNCTION: ghc-supports-smp
150 # @DESCRIPTION:
151 # checks if ghc is built with support for multiple cores runtime
152 ghc-supports-smp() {
153         $(ghc-getghc) --info | grep "Support SMP" | grep -q "YES"
154 }
155
156 # @FUNCTION: ghc-supports-interpreter
157 # @DESCRIPTION:
158 # checks if ghc has interpreter mode (aka GHCi)
159 # It usually means that ghc supports for template haskell.
160 ghc-supports-interpreter() {
161         $(ghc-getghc) --info | grep "Have interpreter" | grep -q "YES"
162 }
163
164 # @FUNCTION: ghc-supports-parallel-make
165 # @DESCRIPTION:
166 # checks if ghc has support for '--make -j' mode
167 # The option was introduced in ghc-7.8-rc1.
168 ghc-supports-parallel-make() {
169         $(ghc-getghc) --info | grep "Support parallel --make" | grep -q "YES"
170 }
171
172 # @FUNCTION: ghc-extractportageversion
173 # @DESCRIPTION:
174 # extract the version of a portage-installed package
175 ghc-extractportageversion() {
176         local pkg
177         local version
178         pkg="$(best_version $1)"
179         version="${pkg#$1-}"
180         version="${version%-r*}"
181         version="${version%_pre*}"
182         echo "${version}"
183 }
184
185 # @FUNCTION: ghc-libdir
186 # @DESCRIPTION:
187 # returns the library directory
188 _GHC_LIBDIR_CACHE=""
189 ghc-libdir() {
190         if [[ -z "${_GHC_LIBDIR_CACHE}" ]]; then
191                 _GHC_LIBDIR_CACHE="$($(ghc-getghc) --print-libdir)"
192         fi
193         echo "${_GHC_LIBDIR_CACHE}"
194 }
195
196 # @FUNCTION: ghc-confdir
197 # @DESCRIPTION:
198 # returns the (Gentoo) library configuration directory, we
199 # store here a hint for 'haskell-updater' about packages
200 # installed for old ghc versions and current ones.
201 ghc-confdir() {
202         echo "$(ghc-libdir)/gentoo"
203 }
204
205 # @FUNCTION: ghc-package-db
206 # @DESCRIPTION:
207 # returns the global package database directory
208 ghc-package-db() {
209         echo "$(ghc-libdir)/package.conf.d"
210 }
211
212 # @FUNCTION: ghc-localpkgconfd
213 # @DESCRIPTION:
214 # returns the name of the local (package-specific)
215 # package configuration file
216 ghc-localpkgconfd() {
217         echo "${PF}.conf.d"
218 }
219
220 # @FUNCTION: ghc-package-exists
221 # @DESCRIPTION:
222 # tests if a ghc package exists
223 ghc-package-exists() {
224         $(ghc-getghcpkg) describe "$1" > /dev/null 2>&1
225 }
226
227 # @FUNCTION: check-for-collisions
228 # @DESCRIPTION: makes sure no packages
229 # have the same version as initial package setup
230 check-for-collisions() {
231         local localpkgconf=$1
232         local checked_pkg
233         local initial_pkg_db="$(ghc-libdir)/package.conf.d.initial"
234
235         for checked_pkg in `$(ghc-getghcpkgbin) -f "${localpkgconf}" list --simple-output`
236         do
237                 # should return empty output
238                 local collided=`$(ghc-getghcpkgbin) -f ${initial_pkg_db} list --simple-output "${checked_pkg}"`
239
240                 if [[ -n ${collided} ]]; then
241                         eerror "Cabal package '${checked_pkg}' is shipped with '$(ghc-pm-version)' ('$(ghc-version)')."
242                         eerror "Ebuild author forgot an entry in CABAL_CORE_LIB_GHC_PV='${CABAL_CORE_LIB_GHC_PV}'."
243                         eerror "Found in ${initial_pkg_db}."
244                         die
245                 fi
246         done
247 }
248
249 # @FUNCTION: ghc-install-pkg
250 # @DESCRIPTION:
251 # moves the local (package-specific) package configuration
252 # file to its final destination
253 ghc-install-pkg() {
254         local pkg_config_file=$1
255         local localpkgconf="${T}/$(ghc-localpkgconfd)"
256         local pkg_path pkg pkg_db="${D}/$(ghc-package-db)" hint_db="${D}/$(ghc-confdir)"
257
258         $(ghc-getghcpkgbin) init "${localpkgconf}" || die "Failed to initialize empty local db"
259         $(ghc-getghcpkgbin) -f "${localpkgconf}" update - --force \
260                 < "${pkg_config_file}" || die "failed to register ${pkg}"
261
262         check-for-collisions "${localpkgconf}"
263
264         mkdir -p "${pkg_db}" || die
265         for pkg_path in "${localpkgconf}"/*.conf; do
266                 pkg=$(basename "${pkg_path}")
267                 cp "${pkg_path}" "${pkg_db}/${pkg}" || die
268         done
269
270         mkdir -p "${hint_db}" || die
271         cp "${pkg_config_file}" "${hint_db}/${PF}.conf" || die
272         chmod 0644 "${hint_db}/${PF}.conf" || die
273 }
274
275 # @FUNCTION: ghc-recache-db
276 # @DESCRIPTION:
277 # updates 'package.cache' binary cacne for registered '*.conf'
278 # packages
279 ghc-recache-db() {
280         einfo "Recaching GHC package DB"
281         $(ghc-getghcpkg) recache
282 }
283
284 # @FUNCTION: ghc-register-pkg
285 # @DESCRIPTION:
286 # registers all packages in the local (package-specific)
287 # package configuration file
288 ghc-register-pkg() {
289         ghc-recache-db
290 }
291
292 # @FUNCTION: ghc-reregister
293 # @DESCRIPTION:
294 # re-adds all available .conf files to the global
295 # package conf file, to be used on a ghc reinstallation
296 ghc-reregister() {
297         ghc-recache-db
298 }
299
300 # @FUNCTION: ghc-unregister-pkg
301 # @DESCRIPTION:
302 # unregisters a package configuration file
303 ghc-unregister-pkg() {
304         ghc-recache-db
305 }
306
307 # @FUNCTION: ghc-pkgdeps
308 # @DESCRIPTION:
309 # exported function: loads a package dependency in a form
310 # cabal_package version
311 ghc-pkgdeps() {
312         echo $($(ghc-getghcpkg) describe "${1}") \
313         | sed \
314                         -e '/depends/,/^.*:/ !d' \
315                         -e 's/\(.*\)-\(.*\)-\(.*\)/\1 \2/' \
316                         -e 's/^.*://g'
317 }
318
319 # @FUNCTION: ghc-package_pkg_postinst
320 # @DESCRIPTION:
321 # updates package.cache after package install
322 ghc-package_pkg_postinst() {
323         ghc-recache-db
324 }
325
326 # @FUNCTION: ghc-package_pkg_prerm
327 # @DESCRIPTION:
328 # updates package.cache after package deinstall
329 ghc-package_pkg_prerm() {
330         ewarn "ghc-package.eclass: 'ghc-package_pkg_prerm()' is a noop"
331         ewarn "ghc-package.eclass: consider 'haskell-cabal_pkg_postrm()' instead"
332 }
333
334 # @FUNCTION: ghc-package_pkg_postrm
335 # @DESCRIPTION:
336 # updates package.cache after package deinstall
337 ghc-package_pkg_postrm() {
338         ghc-recache-db
339 }