This is sat on top of the more cosmetic patch duo I'd sent right before. For full (patch) context, with ebuild porting examples, see also: https://github.com/gentoo/gentoo/pull/44657 (thanks so far to all participants)
---
make_desktop_entry() has so far had no grasp of the importance of Desktop
File ID being consistent with the application ID set by the GUI application
binary itself. To make this work, we need to be able to pass appid as
parameter. Collisions within the ebuild will need to be dealt with
manually, but by way of <appid> this is now possible in the first place.
Losing the -$PN-$SLOT suffix will only slightly increase the potential for
file collisions with other packages - but conflicting desktop file IDs are
problematic anyway and should be resolved in a coordinated effort (e.g. by
fully qualifying the app-id upstream). Otherwise, the occurrence of spaces
in <command> path no longer leads to garbled desktop file naming, however
desirable that may be - <appid> is checked for spec compliant characters.
New arguments:
--eapi9 as first argument to enable new getopts style parameters
As the naming implies, this is off by default for EAPI=[78].
-a|--args to cleanly pass arguments to Exec command
allows us to cleanly get basename from cmd for fallback appid
-d|--appid to set the correct desktop ID, which is the path below
/usr/share/applications plus filename excl. .desktop suffix[1]
-C|--comment to set the desktop file Comment instead of DESCRIPTION
New ECLASS_VARIABLE: _DESKTOP_IDS
Internal array containing app-ids used by make_desktop_entry() calls.
Lets us keep track of/avoid duplicate desktop file names, replacing the
existing "count" suffix.
[1] https://specifications.freedesktop.org/desktop-entry/latest/file-naming.html
Bug: https://bugs.gentoo.org/771708
Bug: https://bugs.gentoo.org/966145
Closes: https://bugs.gentoo.org/290102
Signed-off-by: Andreas Sturmlechner <[email protected]>
---
eclass/desktop.eclass | 197 ++++++++++++++++++++++++++++++++++--------
1 file changed, 159 insertions(+), 38 deletions(-)
diff --git a/eclass/desktop.eclass b/eclass/desktop.eclass
index 9c1e33c1277d..2fbfad1336a5 100644
--- a/eclass/desktop.eclass
+++ b/eclass/desktop.eclass
@@ -15,30 +15,111 @@ case ${EAPI} in
*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
esac
+# @ECLASS_VARIABLE: _DESKTOP_IDS
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Internal array containing any app-ids used by make_desktop_entry() calls.
+# Lets us keep track of/avoid duplicate desktop file names.
+_DESKTOP_IDS=()
+
# @FUNCTION: make_desktop_entry
-# @USAGE: <command> [name] [icon] [categories] [entries]
+# @USAGE: [--eapi9] <command> [options]
# @DESCRIPTION:
# Make a .desktop file.
#
# @CODE
+# --eapi9: Switch to getopts style arguments instead of order based
+# As the naming implies, this is off by default for EAPI=[78],
+# but mandated by future EAPI.
# command: Exec command the app is being run with, also base for TryExec
+# --- Options:
# name: Name that will show up in the menu; defaults to PN
+# with --eapi9: must not contain arguments, use --args for that
# icon: Icon to use with the menu entry; defaults to PN
# this can be relative (to /usr/share/pixmaps) or
# a full path to an icon
# categories: Categories for this kind of application. Examples:
# https://specifications.freedesktop.org/menu-spec/latest/apa.html
# if unset, function tries to guess from package's category
-# entries: Key=Value entry to append to the desktop file; a printf string
+# entry: Key=Value entry to append to the desktop file;
+# with --eapi9: multiple allowed; old style: a printf string
+# --- Additional parameters available using --eapi9:
+# args: Arguments (binary params and desktop spec field codes) to add
+# to Exec value, separated by a space if multiple
+# appid: <appid>.desktop will be created. must be same as appid defined
+# in code (including reverse qualified domain if set);
+# defaults to <command>
+# comment: Comment (menu entry tooltip), defaults to DESCRIPTION
+# @CODE
+#
+# Example usage:
+# @CODE
+# Deprecated, in order:
+# <command> [name] [icon] [categories] [entries...]
+# New style:
+# --eapi9 <command> [-a args] [-d appid] [-C comment] [-i icon]
+# --eapi9 <command> [-n name] [-e entry...] [-c categories]
# @CODE
make_desktop_entry() {
- [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable"
+ local eapi9
+ if [[ -n ${1} ]]; then
+ case ${EAPI} in
+ 7|8)
+ if [[ ${1} == --eapi9 ]]; then
+ eapi9=1
+ shift
+ fi
+ ;;
+ *)
+ if [[ ${1} == --eapi9 ]]; then
+ ewarn "make_desktop_entry: --eapi9 arg
is obsolete in EAPI-${EAPI} and may be cleaned up now."
+ shift
+ fi
+ eapi9=1
+ ;;
+ esac
+ fi
+ [[ -z ${1} ]] && die "make_desktop_entry: You must specify at least a
command"
+
+ if [[ ${eapi9} ]]; then
+ local appid args cats cmd comment entries icon name
+ while [[ $# -gt 0 ]] ; do
+ case "${1}" in
+ -a|--args)
+ args="${2}"; shift 2 ;;
+ -c|--categories)
+ cats="${2}"; shift 2 ;;
+ -C|--comment)
+ comment="${2}"; shift 2 ;;
+ -d|--appid)
+ appid="${2}"; shift 2 ;;
+ -e|--entry)
+ entries+=( "${2}" ); shift 2 ;;
+ -i|--icon)
+ icon="${2}"; shift 2 ;;
+ -n|--name)
+ name="${2}"; shift 2 ;;
+ *)
+ if [[ -z ${cmd} ]] ; then
+ cmd="${1}"
+ else
+ die "make_desktop_entry: Can only take
one command! First got: ${cmd}; then got: ${1}"
+ fi
+ shift ;;
+ esac
+ done
+ [[ -z ${cmd} ]] && die "make_desktop_entry: You must specify at
least a command"
+ [[ -z ${name} ]] && name=${PN}
+ [[ -z ${icon} ]] && icon=${PN}
+ else
+ local cmd=${1}
+ local name=${2:-${PN}}
+ local icon=${3:-${PN}}
+ local cats=${4}
+ local entries=${5}
+ fi
- local cmd=${1}
- local name=${2:-${PN}}
- local icon=${3:-${PN}}
- local cats=${4}
- local entries=${5}
+ [[ -z ${comment} ]] && comment="${DESCRIPTION}"
if [[ -z ${cats} ]] ; then
local catmaj=${CATEGORY%%-*}
@@ -162,19 +243,37 @@ make_desktop_entry() {
esac
fi
- local desktop_exec="${cmd%%[[:space:]]*}"
- desktop_exec="${desktop_exec##*/}"
- local desktop_suffix="-${PN}"
- [[ ${SLOT%/*} != 0 ]] && desktop_suffix+="-${SLOT%/*}"
- # Replace foo-foo.desktop by foo.desktop
- [[ ${desktop_suffix#-} == "${desktop_exec}" ]] && desktop_suffix=""
-
- # Prevent collisions if a file with the same name already exists #771708
- local desktop="${desktop_exec}${desktop_suffix}" count=0
- while [[ -e ${ED}/usr/share/applications/${desktop}.desktop ]]; do
- desktop="${desktop_exec}-$((++count))${desktop_suffix}"
- done
- desktop="${T}/${desktop}.desktop"
+ if [[ ${eapi9} ]]; then
+ if [[ -z ${appid} ]]; then
+ if [[ ${cmd} =~ .+[[:space:]].+ ]]; then
+ die "make_desktop_entry: --appid must be
provided when <command> contains a space"
+ fi
+ appid="${cmd##*/}"
+ fi
+ if [[ ! ${appid} =~ ^[A-Za-z0-9._-]+$ ]]; then
+ die "make_desktop_entry: <appid> must only consist of
ASCII letters, digits, dash, underscore and dots"
+ fi
+ if [[ ${_DESKTOP_IDS[*]} =~
(^|[[:space:]])"${appid}"($|[[:space:]]) ]]; then
+ die "make_desktop_entry: appid \"${appid}\" already
used in a previous call, choose a different one"
+ else
+ _DESKTOP_IDS+=( "${appid}" )
+ fi
+ local desktop="${T}/${appid}.desktop"
+ else
+ local desktop_exec="${cmd%%[[:space:]]*}"
+ desktop_exec="${desktop_exec##*/}"
+ local desktop_suffix="-${PN}"
+ [[ ${SLOT%/*} != 0 ]] && desktop_suffix+="-${SLOT%/*}"
+ # Replace foo-foo.desktop by foo.desktop
+ [[ ${desktop_suffix#-} == "${desktop_exec}" ]] &&
desktop_suffix=""
+
+ # Prevent collisions if a file with the same name already
exists #771708
+ local desktop="${desktop_exec}${desktop_suffix}" count=0
+ while [[ -e ${ED}/usr/share/applications/${desktop}.desktop ]];
do
+ desktop="${desktop_exec}-$((++count))${desktop_suffix}"
+ done
+ desktop="${T}/${desktop}.desktop"
+ fi
# Don't append another ";" when a valid category value is provided.
cats=${cats%;}${cats:+;}
@@ -185,24 +284,46 @@ make_desktop_entry() {
icon=${icon%.*}
fi
- cat <<-EOF > "${desktop}" || die
- [Desktop Entry]
- Name=${name}
- Type=Application
- Comment=${DESCRIPTION}
- Exec=${cmd}
- TryExec=${cmd%% *}
- Icon=${icon}
- Categories=${cats}
- EOF
-
- if [[ ${entries:-=} != *=* ]] ; then
- # 5th arg used to be value to Path=
- ewarn "make_desktop_entry: update your 5th arg to read
Path=${entries}"
- entries="Path=${entries}"
+ cat > "${desktop}" <<- _EOF_ || die
+ [Desktop Entry]
+ Type=Application
+ Name=${name}
+ Comment=${comment}
+ Icon=${icon}
+ Categories=${cats}
+ _EOF_
+
+ if [[ ${eapi9} ]]; then
+ local cmd_args="${cmd} ${args}"
+ cat >> "${desktop}" <<- _EOF_ || die
+ Exec=${cmd_args%[[:space:]]}
+ TryExec=${cmd}
+ _EOF_
+ else
+ cat >> "${desktop}" <<- _EOF_ || die
+ Exec=${cmd}
+ TryExec=${cmd%% *}
+ _EOF_
fi
- if [[ -n ${entries} ]]; then
- printf '%b\n' "${entries}" >> "${desktop}" || die
+
+ if [[ ${eapi9} && -n ${entries} ]]; then
+ local entry
+ for entry in ${entries[@]}; do
+ if [[ ${entry} =~ ^[A-Za-z0-9-]+=.* ]]; then
+ printf "%s\n" "${entry}" >> "${desktop}" || die
+ else
+ die "make_desktop_entry: <entry> \"${entry}\"
rejected; must be passed a Key=Value pair"
+ fi
+ done
+ else
+ if [[ ${entries:-=} != *=* ]]; then
+ # 5th arg used to be value to Path=
+ ewarn "make_desktop_entry: update your 5th arg to read
Path=${entries}"
+ entries="Path=${entries}"
+ fi
+ if [[ -n ${entries} ]]; then
+ printf '%b\n' "${entries}" >> "${desktop}" || die
+ fi
fi
(
--
2.51.2
signature.asc
Description: This is a digitally signed message part.
