sys-process/glances: 3.1.4.1-r1 amd64 stable, bug #720368
[gentoo.git] / eclass / savedconfig.eclass
1 # Copyright 1999-2020 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: savedconfig.eclass
5 # @MAINTAINER:
6 # base-system@gentoo.org
7 # @SUPPORTED_EAPIS: 5 6 7
8 # @BLURB: common API for saving/restoring complex configuration files
9 # @DESCRIPTION:
10 # It is not uncommon to come across a package which has a very fine
11 # grained level of configuration options that go way beyond what
12 # USE flags can properly describe.  For this purpose, a common API
13 # of saving and restoring the configuration files was developed
14 # so users can modify these config files and the ebuild will take it
15 # into account as needed.
16 #
17 # Typically you can create your own configuration files quickly by
18 # doing:
19 #
20 # 1. Build the package with FEATURES=noclean USE=savedconfig.
21 #
22 # 2. Go into the build dir and edit the relevant configuration system
23 # (e.g. `make menuconfig` or `nano config-header.h`).  You can look
24 # at the files in /etc/portage/savedconfig/ to see what files get
25 # loaded/restored.
26 #
27 # 3. Copy the modified configuration files out of the workdir and to
28 # the paths in /etc/portage/savedconfig/.
29 #
30 # 4. Emerge the package with just USE=savedconfig to get the custom
31 # build.
32
33 inherit portability
34
35 IUSE="savedconfig"
36
37 case ${EAPI} in
38         [5-7]) ;;
39         *) die "EAPI=${EAPI:-0} is not supported" ;;
40 esac
41
42 # @ECLASS-VARIABLE: _SAVEDCONFIG_CONFIGURATION_FILE
43 # @DEFAULT_UNSET
44 # @INTERNAL
45 # @DESCRIPTION:
46 # Path of configuration file, relative to /etc/portage/savedconfig,
47 # restored by restore_config() and saved by save_config().
48
49 # @FUNCTION: save_config
50 # @USAGE: <config files to save>
51 # @DESCRIPTION:
52 # Use this function to save the package's configuration file into the
53 # right location.  You may specify any number of configuration files,
54 # but just make sure you call save_config with all of them at the same
55 # time in order for things to work properly.
56 save_config() {
57         if [[ ${EBUILD_PHASE} != "install" ]]; then
58                 die "Bad package!  save_config only for use in src_install functions!"
59         fi
60         [[ $# -eq 0 ]] && die "Usage: save_config <files>"
61
62         local configfile
63         if [[ -n ${_SAVEDCONFIG_CONFIGURATION_FILE} ]] ; then
64                 configfile="/etc/portage/savedconfig/${_SAVEDCONFIG_CONFIGURATION_FILE}"
65         else
66                 configfile="/etc/portage/savedconfig/${CATEGORY}/${PF}"
67         fi
68
69         if [[ $# -eq 1 && -f $1 ]] ; then
70                 # Just one file, so have the ${configfile} be that config file
71                 dodir "${configfile%/*}"
72                 cp "$@" "${ED%/}/${configfile}" || die "failed to save $*"
73         else
74                 # A dir, or multiple files, so have the ${configfile} be a dir
75                 # with all the saved stuff below it
76                 dodir "${configfile}"
77                 treecopy "$@" "${ED%/}/${configfile}" || die "failed to save $*"
78         fi
79
80         elog "Your configuration for ${CATEGORY}/${PF} has been saved in "
81         elog "\"${configfile}\" for your editing pleasure."
82         elog "You can edit these files by hand and remerge this package with"
83         elog "USE=savedconfig to customise the configuration."
84         elog "You can rename this file/directory to one of the following for"
85         elog "its configuration to apply to multiple versions:"
86         elog '${PORTAGE_CONFIGROOT}/etc/portage/savedconfig/'
87         elog '[${CTARGET}|${CHOST}|""]/${CATEGORY}/[${PF}|${P}|${PN}]'
88 }
89
90 # @FUNCTION: restore_config
91 # @USAGE: <config files to restore>
92 # @DESCRIPTION:
93 # Restores the package's configuration file probably with user edits.
94 # You can restore a single file or a whole bunch, just make sure you call
95 # restore_config with all of the files to restore at the same time.
96 #
97 # Config files can be laid out as:
98 # @CODE
99 # ${PORTAGE_CONFIGROOT}/etc/portage/savedconfig/${CTARGET}/${CATEGORY}/${PF}
100 # ${PORTAGE_CONFIGROOT}/etc/portage/savedconfig/${CHOST}/${CATEGORY}/${PF}
101 # ${PORTAGE_CONFIGROOT}/etc/portage/savedconfig/${CATEGORY}/${PF}
102 # ${PORTAGE_CONFIGROOT}/etc/portage/savedconfig/${CTARGET}/${CATEGORY}/${P}
103 # ${PORTAGE_CONFIGROOT}/etc/portage/savedconfig/${CHOST}/${CATEGORY}/${P}
104 # ${PORTAGE_CONFIGROOT}/etc/portage/savedconfig/${CATEGORY}/${P}
105 # ${PORTAGE_CONFIGROOT}/etc/portage/savedconfig/${CTARGET}/${CATEGORY}/${PN}
106 # ${PORTAGE_CONFIGROOT}/etc/portage/savedconfig/${CHOST}/${CATEGORY}/${PN}
107 # ${PORTAGE_CONFIGROOT}/etc/portage/savedconfig/${CATEGORY}/${PN}
108 # @CODE
109 restore_config() {
110         case ${EBUILD_PHASE} in
111                 unpack|compile|configure|prepare) ;;
112                 *) die "Bad package!  restore_config only for use in src_{unpack,compile,configure,prepare} functions!" ;;
113         esac
114
115         use savedconfig || return
116
117         local found check checked configfile
118         local base=${PORTAGE_CONFIGROOT%/}/etc/portage/savedconfig
119         for check in {${CATEGORY}/${PF},${CATEGORY}/${P},${CATEGORY}/${PN}}; do
120                 configfile=${base}/${CTARGET:+"${CTARGET}/"}${check}
121                 [[ -r ${configfile} ]] || configfile=${base}/${CHOST:+"${CHOST}/"}${check}
122                 [[ -r ${configfile} ]] || configfile=${base}/${check}
123                 [[ "${checked}" == *"${configfile} "* ]] && continue
124                 einfo "Checking existence of \"${configfile}\" ..."
125                 if [[ -r "${configfile}" ]] ; then
126                         einfo "Found \"${configfile}\""
127                         found=${configfile}
128                         _SAVEDCONFIG_CONFIGURATION_FILE=${configfile#${base}/}
129                         break
130                 fi
131
132                 checked+="${configfile} "
133         done
134
135         if [[ -f ${found} ]]; then
136                 elog "Building using saved configfile \"${found}\""
137                 if [ $# -gt 0 ]; then
138                         cp -pPR "${found}" "$1" || die "Failed to restore ${found} to $1"
139                 else
140                         die "need to know the restoration filename"
141                 fi
142         elif [[ -d ${found} ]]; then
143                 elog "Building using saved config directory \"${found}\""
144                 local dest=${PWD}
145                 pushd "${found}" > /dev/null
146                 treecopy . "${dest}" || die "Failed to restore ${found} to $1"
147                 popd > /dev/null
148         else
149                 # maybe the user is screwing around with perms they shouldnt #289168
150                 if [[ ! -r ${base} ]] ; then
151                         eerror "Unable to read ${base} -- please check its permissions."
152                         die "Reading config files failed"
153                 fi
154                 ewarn "No saved config to restore - please remove USE=savedconfig or"
155                 ewarn "provide a configuration file in ${PORTAGE_CONFIGROOT%/}/etc/portage/savedconfig/${CATEGORY}/${PN}"
156                 ewarn "Your config file(s) will not be used this time"
157         fi
158 }
159
160 savedconfig_pkg_postinst() {
161         # If the user has USE=savedconfig, then chances are they
162         # are modifying these files, so keep them around.  #396169
163         # This might lead to cruft build up, but the alternatives
164         # are worse :/.
165
166         if use savedconfig ; then
167                 find "${EROOT%/}/etc/portage/savedconfig/${CATEGORY}/${PF}" \
168                         -exec touch {} + 2>/dev/null
169         fi
170 }
171
172 EXPORT_FUNCTIONS pkg_postinst