1 # Copyright 1999-2020 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
4 # @ECLASS: savedconfig.eclass
6 # base-system@gentoo.org
7 # @SUPPORTED_EAPIS: 5 6 7
8 # @BLURB: common API for saving/restoring complex configuration files
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.
17 # Typically you can create your own configuration files quickly by
20 # 1. Build the package with FEATURES=noclean USE=savedconfig.
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
27 # 3. Copy the modified configuration files out of the workdir and to
28 # the paths in /etc/portage/savedconfig/.
30 # 4. Emerge the package with just USE=savedconfig to get the custom
39 *) die "EAPI=${EAPI:-0} is not supported" ;;
42 # @ECLASS-VARIABLE: _SAVEDCONFIG_CONFIGURATION_FILE
46 # Path of configuration file, relative to /etc/portage/savedconfig,
47 # restored by restore_config() and saved by save_config().
49 # @FUNCTION: save_config
50 # @USAGE: <config files to save>
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.
57 if [[ ${EBUILD_PHASE} != "install" ]]; then
58 die "Bad package! save_config only for use in src_install functions!"
60 [[ $# -eq 0 ]] && die "Usage: save_config <files>"
63 if [[ -n ${_SAVEDCONFIG_CONFIGURATION_FILE} ]] ; then
64 configfile="/etc/portage/savedconfig/${_SAVEDCONFIG_CONFIGURATION_FILE}"
66 configfile="/etc/portage/savedconfig/${CATEGORY}/${PF}"
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 $*"
74 # A dir, or multiple files, so have the ${configfile} be a dir
75 # with all the saved stuff below it
77 treecopy "$@" "${ED%/}/${configfile}" || die "failed to save $*"
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}]'
90 # @FUNCTION: restore_config
91 # @USAGE: <config files to restore>
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.
97 # Config files can be laid out as:
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}
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!" ;;
115 use savedconfig || return
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}\""
128 _SAVEDCONFIG_CONFIGURATION_FILE=${configfile#${base}/}
132 checked+="${configfile} "
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"
140 die "need to know the restoration filename"
142 elif [[ -d ${found} ]]; then
143 elog "Building using saved config directory \"${found}\""
145 pushd "${found}" > /dev/null
146 treecopy . "${dest}" || die "Failed to restore ${found} to $1"
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"
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"
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
166 if use savedconfig ; then
167 find "${EROOT%/}/etc/portage/savedconfig/${CATEGORY}/${PF}" \
168 -exec touch {} + 2>/dev/null
172 EXPORT_FUNCTIONS pkg_postinst