This new eclass includes various improvements over the existing readme.gentoo-r1.eclass.
First, the content of README.gento will only be shown on new
installations or if it has changed between updates.
Second, it allows the composition of readme via bash's heredoc.
Third, it exports phase functions, which helps to reduce the boilerplate
code in many cases.
Finally, unlike readme.gentoo-r1.elcass, this eclass does not need to
store the content of the readme in an environment variable. Not having
to store the content in an environment variable reduces the pollution of
the environment (sadly, this only refers to the process environment).
Signed-off-by: Florian Schmaus <flow@gentoo.org>
---
eclass/greadme.eclass | 240 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 240 insertions(+)
create mode 100644 eclass/greadme.eclass
diff --git a/eclass/greadme.eclass b/eclass/greadme.eclass
new file mode 100644
index 000000000000..ddbcc8e9858d
--- /dev/null
+++ b/eclass/greadme.eclass
@@ -0,0 +1,240 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: greadme.eclass
+# @MAINTAINER:
+# Florian Schmaus <flow@gentoo.org>
+# @AUTHOR:
+# Author: Florian Schmaus <flow@gentoo.org>
+# @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_FILENAME="README.gentoo" +_GREADME_TMP_FILE="${T}/${_GREADME_FILENAME}" +_GREADME_REL_PATH="/usr/share/doc/${PF}/${_GREADME_FILENAME}"
+
+# @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.
+
+# @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
+ while [[ -n ${1} ]] && [[ ${1} == --* ]]; do
+ case ${1} in
+ --append)
+ append=1
+ shift
+ ;;
+ esac
+ done
+
+ 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
+ if [[ -f ${_GREADME_TMP_FILE} ]]; then
+ die "Gentoo README already exists while trying to create it"
+ fi
+
+ cat > "${_GREADME_TMP_FILE}" || die
+ fi
+
+ _greadme_install_doc
+}
+
+# @FUNCTION: greadme_file
+# @USAGE: <file>
+# @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
+
+ if [[ -f ${_GREADME_TMP_FILE} ]]; then
+ die "Gentoo README already exists"
+ 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} "${@}"
+
+ # Subshell to avoid pollution of calling environment.
+ (
+ docinto .
+ dodoc "${_GREADME_TMP_FILE}"
+ )
+
+ # Exclude the readme file from compression, so that its contents can
+ # be easily compared.
+ docompress -x "${_GREADME_REL_PATH}"
+}
+
+# @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
+ # No README file was created by the ebuild.
+ _GREADME_SHOW=""
+ return
+ fi
+
+ check_live_doc_file() {
+ local cur_pvr=$1
+ local live_greadme_file="${EROOT}/usr/share/doc/${PN}-${cur_pvr}/${_GREADME_FILENAME}"
+
+ if [[ ! -f ${live_greadme_file} ]]; then
+ _GREADME_SHOW="no-current-greadme"
+ return
+ fi
+
+ cmp -s "${live_greadme_file}" "${image_greadme_file}"
+ local ret=$?
+ case ${ret} in
+ 0)
+ _GREADME_SHOW=""
+ ;;
+ 1)
+ _GREADME_SHOW="content-differs"
+ ;;
+ *)
+ die "cmp failed with ${ret}"
+ ;;
+ 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 greadme="${EROOT}${_GREADME_REL_PATH}"
+
+ if [[ ! -f ${greadme} ]]; then
+ ewarn "Unable to show ${_GREADME_FILENAME}, file not installed (FEATURES=nodoc enabled?)."
+ return
+ fi
+
+ local line
+ while read -r line; do elog "${line}"; done < "${greadme}"
+ elog ""
+ elog "(Note: Above message is only printed the first time package is"
+ elog "installed or if the message changes on update. Please look at"
+ elog "${EPREFIX}${_GREADME_REL_PATH} for future reference)"
+}
+
+fi
+
+EXPORT_FUNCTIONS pkg_preinst pkg_postinst
On Sun, 16 Jun 2024, Florian Schmaus wrote:
First, the content of README.gento will only be shown on new
+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 greadme="${EROOT}${_GREADME_REL_PATH}"
+
+ if [[ ! -f ${greadme} ]]; then
+ ewarn "Unable to show ${_GREADME_FILENAME}, file not installed (FEATURES=nodoc enabled?)."
+ return
+ fi
+
+ local line
+ while read -r line; do elog "${line}"; done < "${greadme}"
+ elog ""
+ elog "(Note: Above message is only printed the first time package is"
+ elog "installed or if the message changes on update. Please look at"
+ elog "${EPREFIX}${_GREADME_REL_PATH} for future reference)"
+}
On Tue, 18 Jun 2024, Florian Schmaus wrote:
Finally, unlike readme.gentoo-r1.elcass, this eclass does not need
to store the content of the readme in an environment variable. Not
having to store the content in an environment variable reduces the
pollution of the environment (sadly, this only refers to the process
environment).
I'll be honest, I never felt this is really needed? From looking at
the current -r1 eclass, you could define DOC_CONTENTS just before
invoking readme.gentoo_create_doc, so you could for example modify as
you want the message and use `local DOC_CONTENTS="..."`.
readme.gentoo-r1.eclass requires DOC_CONTENTS to be part of the
package's environment to show it later in readme.gentoo_print_elog(),
which is typically invoked in pkg_postinst(). If DOC_CONTENTS is local
to readme.gentoo_create_doc(), then it wont be able in pkg_postinst()
and can potentially not be obtained from the README.gentoo file
because that file may be compressed.
For greadme.eclass, the file is no longer compressed, therefore greadme.eclass does not need to carry a variable in the package's environment.
On 18/06/2024 17.53, Florian Schmaus wrote:
On 18/06/2024 16.02, Ulrich Mueller wrote:
Finally, unlike readme.gentoo-r1.elcass, this eclass does not need >>>>> to store the content of the readme in an environment variable. Not >>>>> having to store the content in an environment variable reduces the >>>>> pollution of the environment (sadly, this only refers to the process >>>>> environment).On Tue, 18 Jun 2024, Florian Schmaus wrote:
I'll be honest, I never felt this is really needed? From looking at
the current -r1 eclass, you could define DOC_CONTENTS just before
invoking readme.gentoo_create_doc, so you could for example modify as >>>> you want the message and use `local DOC_CONTENTS="..."`.
readme.gentoo-r1.eclass requires DOC_CONTENTS to be part of the
package's environment to show it later in readme.gentoo_print_elog(),
which is typically invoked in pkg_postinst(). If DOC_CONTENTS is local >>> to readme.gentoo_create_doc(), then it wont be able in pkg_postinst()
and can potentially not be obtained from the README.gentoo file
because that file may be compressed.
For greadme.eclass, the file is no longer compressed, therefore
greadme.eclass does not need to carry a variable in the package's
environment.
These are two different variables that must not be confused >>[DOC_CONTENTS vs README_GENTOO_DOC_VALUE].
Thanks for pointing this out. I think I understand now what arthur is asking for:
src_install() {
...
local DOC_CONTENTS="My README.Gentoo contents"
readme.gentoo_create_doc
}
@arthur: is that right?
yes, exactly. Please, I suggest going over the existing eclass, you
might get surprised how much is supported already.
If so, then we could always add such an API to greadme.eclass too.
However, it appears that it simply would duplicate what can already be
done via greadme_stdin. Is there a compelling reason for such an API
that I am missing?
In any case, I wouldn't be opposed to implement something like this if somebody asks for it.
I think you are looking at it from the wrong side. Thinking in this
"impl" possible now, I think *you* are duplicating work stuff which was supported in readme.gentoo-r1. I don't see anything supportted by greadme_stdin and unsupported with this `local DOC_CONTENTS` stuff.
What I'm trying to push you into, is understanding if you really need a
new eclass. With all of those things, I believe greadme eclass is just a duplicate.
I think if there is a small thing you want to have in -r1 eclass, it is already supported or easily added. The support for a $FILESDIR is
something I see more rare than direct DOC_CONTENTS (in global as common,
and as local as a possible way).
BTW, I like readme.gentoo-r1's autoformatting, because the message may
contain variables (like paths containing EPREFIX) that can expand to
different lengths.
Happy to add it.
Any preference regarding the auto-formatting tool? The readme.gentoo-r1.eclass uses fold, but fmt (both are in coreutils) would probably also be an option (and has a --uniform-spacing option ;)).
- Flow
--
Arthur Zamarin
arthurzam@gentoo.org
Gentoo Linux developer (Python, pkgcore stack, QA, Arch Teams, GURU)
On 18/06/2024 16.02, Ulrich Mueller wrote:
Finally, unlike readme.gentoo-r1.elcass, this eclass does not needOn Tue, 18 Jun 2024, Florian Schmaus wrote:
to store the content of the readme in an environment variable. Not
having to store the content in an environment variable reduces the
pollution of the environment (sadly, this only refers to the process >>>>> environment).
I'll be honest, I never felt this is really needed? From looking at
the current -r1 eclass, you could define DOC_CONTENTS just before
invoking readme.gentoo_create_doc, so you could for example modify as
you want the message and use `local DOC_CONTENTS="..."`.
readme.gentoo-r1.eclass requires DOC_CONTENTS to be part of the
package's environment to show it later in readme.gentoo_print_elog(),
which is typically invoked in pkg_postinst(). If DOC_CONTENTS is local
to readme.gentoo_create_doc(), then it wont be able in pkg_postinst()
and can potentially not be obtained from the README.gentoo file
because that file may be compressed.
For greadme.eclass, the file is no longer compressed, therefore
greadme.eclass does not need to carry a variable in the package's
environment.
These are two different variables that must not be confused
[DOC_CONTENTS vs README_GENTOO_DOC_VALUE].
Thanks for pointing this out. I think I understand now what arthur is
asking for:
src_install() {
...
local DOC_CONTENTS="My README.Gentoo contents"
readme.gentoo_create_doc
}
@arthur: is that right?
If so, then we could always add such an API to greadme.eclass too.
However, it appears that it simply would duplicate what can already be
done via greadme_stdin. Is there a compelling reason for such an API
that I am missing?
In any case, I wouldn't be opposed to implement something like this if somebody asks for it.
BTW, I like readme.gentoo-r1's autoformatting, because the message may
contain variables (like paths containing EPREFIX) that can expand to
different lengths.
Happy to add it.
Any preference regarding the auto-formatting tool? The readme.gentoo-r1.eclass uses fold, but fmt (both are in coreutils) would probably also be an option (and has a --uniform-spacing option ;)).
- Flow
On Tue, 18 Jun 2024, Florian Schmaus wrote:
Any preference regarding the auto-formatting tool? The readme.gentoo-r1.eclass uses fold, but fmt (both are in coreutils)
would probably also be an option (and has a --uniform-spacing option
;)).
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 407 |
Nodes: | 16 (2 / 14) |
Uptime: | 15:35:04 |
Calls: | 8,555 |
Calls today: | 7 |
Files: | 13,219 |
Messages: | 5,925,665 |