# Copyright 1999-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 # @ECLASS: greadme.eclass # @MAINTAINER: # Florian Schmaus # @SUPPORTED_EAPIS: 8 # @BLURB: install a doc file, that will be conditionally shown via elog messages # @DESCRIPTION: # An eclass for installing a README.gentoo doc file with important # information for the user. The content of README.gentoo will shown be # via elog messages either on fresh installations or if the contents of # the file have changed. Furthermore, the README.gentoo file will be # installed under /usr/share/doc/${PF} for later consultation. # # This eclass was inspired by readme.gentoo-r1.eclass. The main # differences are as follows. Firstly, it only displays the doc file # contents if they have changed (unless GREADME_SHOW is set). # Secondly, it provides a convenient API to install the doc file via # stdin. # # @CODE # inherit greadme # # src_install() { # ... # greadme_stdin <<-EOF # This is the content of the created readme doc file. # EOF # ... # if use foo; then # greadme_stdin --append <<-EOF # This is conditional readme content, based on USE=foo. # EOF # fi # } # @CODE # # If the ebuild overrides the default pkg_preinst or respectively # pkg_postinst, then it must call greadme_pkg_preinst and # greadme_pkg_postinst explicitly. if [[ -z ${_GREADME_ECLASS} ]]; then _GREADME_ECLASS=1 case ${EAPI} in 8) ;; *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; esac _GREADME_TMP_FILE="${T}/README.gentoo" _GREADME_REL_PATH="/usr/share/doc/${PF}/README.gentoo" # @ECLASS_VARIABLE: GREADME_SHOW # @DEFAULT_UNSET # @DESCRIPTION: # If set to "yes" then unconditionally show the contents of the readme # file in pkg_postinst via elog. If set to "no", then do not show the # contents of the readme file, even if they have changed. # @ECLASS_VARIABLE: GREADME_DISABLE_AUTOFORMAT # @DEFAULT_UNSET # @DESCRIPTION: # If non-empty, the readme file will not be automatically formatted. # @FUNCTION: greadme_stdin # @USAGE: [--append] # @DESCRIPTION: # Create the readme doc via stdin. You can use --append to append to an # existing readme doc. greadme_stdin() { debug-print-function ${FUNCNAME} "${@}" local append if [[ ${1} = --append ]]; then append=1 shift fi [[ $# -eq 0 ]] || die "${FUNCNAME[0]}: Bad parameters: $*" if [[ -n ${append} ]]; then if [[ ! -f ${_GREADME_TMP_FILE} ]]; then die "Gentoo README does not exist when trying to append to it" fi cat >> "${_GREADME_TMP_FILE}" || die else cat > "${_GREADME_TMP_FILE}" || die fi _greadme_install_doc } # @FUNCTION: greadme_file # @USAGE: # @DESCRIPTION: # Installs the provided file as readme doc. greadme_file() { debug-print-function ${FUNCNAME} "${@}" local input_doc_file="${1}" if [[ -z ${input_doc_file} ]]; then die "No file specified" fi cp "${input_doc_file}" "${_GREADME_TMP_FILE}" || die _greadme_install_doc } # @FUNCTION: _greadme_install_doc # @INTERNAL # @DESCRIPTION: # Installs the readme file from the temp directory into the image. _greadme_install_doc() { debug-print-function ${FUNCNAME} "${@}" local greadme="${_GREADME_TMP_FILE}" if [[ ! ${GREADME_DISABLE_AUTOFORMAT} ]]; then greadme="${_GREADME_TMP_FILE}".formatted # Use fold, followed by a sed to strip trailing whitespace. # https://bugs.gentoo.org/460050#c7 fold -s -w 70 "${_GREADME_TMP_FILE}" | sed 's/[[:space:]]*$//' > "${greadme}" assert "failed to autoformat README.gentoo" fi # Subshell to avoid pollution of calling environment. ( docinto . newdoc "${greadme}" "README.gentoo" ) # Exclude the readme file from compression, so that its contents can # be easily compared. docompress -x "${_GREADME_REL_PATH}" # Save the contents of the of the readme. Unfortunately we have to # do this in src_* phase, because FEATURES=nodoc is applied right # after src_install and not after pkg_preinst. _GREADME_CONTENT=$(< "${greadme}") } # @FUNCTION: greadme_pkg_preinst # @DESCRIPTION: # Performs checks like comparing the readme doc from the image with a # potentially existing one in the live system. greadme_pkg_preinst() { debug-print-function ${FUNCNAME} "${@}" if [[ -z ${REPLACING_VERSIONS} ]]; then _GREADME_SHOW="fresh-install" return fi if [[ -v GREADME_SHOW ]]; then case ${GREADME_SHOW} in yes) _GREADME_SHOW="forced" ;; no) _GREADME_SHOW="" ;; *) die "Invalid argument of GREADME_SHOW: ${GREADME_SHOW}" ;; esac return fi local image_greadme_file="${ED}${_GREADME_REL_PATH}" if [[ ! -f ${image_greadme_file} ]]; then if [[ -v _GREADME_CONTENT ]]; then # There is no greadme in the image but the ebuild created # one. This is likely because FEATURES=nodoc is active. # Unconditionally show greadme's contents. _GREADME_SHOW="nodoc-active" else # No README file was created by the ebuild. _GREADME_SHOW="" fi return fi check_live_doc_file() { local cur_pvr=$1 local live_greadme_file="${EROOT}/usr/share/doc/${PN}-${cur_pvr}/README.gentoo" if [[ ! -f ${live_greadme_file} ]]; then _GREADME_SHOW="no-current-greadme" return fi cmp -s "${live_greadme_file}" "${image_greadme_file}" case $? in 0) _GREADME_SHOW="" ;; 1) _GREADME_SHOW="content-differs" ;; *) die "cmp failed with $?" ;; esac } local replaced_version for replaced_version in ${REPLACING_VERSIONS}; do check_live_doc_file ${replaced_version} # Once _GREADME_SHOW is non empty, we found a reason to show the # readme and we can abort the loop. if [[ -n ${_GREADME_SHOW} ]]; then break fi done } # @FUNCTION: greadme_pkg_postinst # @DESCRIPTION: # Conditionally shows the contents of the readme doc via elog. greadme_pkg_postinst() { debug-print-function ${FUNCNAME} "${@}" if [[ ! -v _GREADME_SHOW ]]; then die "_GREADME_SHOW not set. Did you call greadme_pkg_preinst?" fi if [[ -z ${_GREADME_SHOW} ]]; then # If _GREADME_SHOW is empty, then there is no reason to show the contents. return fi local line printf '%s\n' "${_GREADME_CONTENT}" | while read -r line; do elog "${line}" done elog "" elog "NOTE: Above message is only printed the first time package is" elog "installed or if the message changed. Please look at" elog "${EPREFIX}${_GREADME_REL_PATH}" elog "for future reference." } fi EXPORT_FUNCTIONS pkg_preinst pkg_postinst