Gentoo’s HP printer drivers package, net-print/hplip, if you have the gui USE flags enabled, installs /etc/xdg/autostart/hplip-systray.desktop, which makes an awful Windows-like tray app load with all desktop environments for every user on the machine. Who wants this? Every user? Tray app? Autostart? This is Linux, not Windows, right?

Upstream, i.e. Gentoo devs, doesn’t seem to want to add an autostart USE flag. I don’t feel like maintaining my own ebuild for this, either. So, the official advice is to copy hplip-systray.desktop into a special place in your own home folder, and then edit the file to have Hidden=true. Yuck. So now my start-up routine will have to spend extra CPU cycles resolving the override, not to mention the requirement for each and every user on my machine to do this. Sure I could add this extra file to the default set of files copied into each home folder on user creation for each desktop environment, but do I really want to do this? What about preexisting users? Do I really want this system installed package to require this kind of manual intervention? The obvious thing to do is just to delete /etc/xdg/autostart/hplip-systray.desktop after each time hplip installs, namely, after each update.

But the official advice calls this approach “naive”. Fuck that. I don’t want the extra overhead of working out the collision, nor do I want to have to add this file to each user’s home folder. I want that file gone, dead, vamos‘d. The thing is, it means I have to manually remove the file after each time the ebuild gets updated (and remember, I don’t want to maintain my own fork of the ebuild).

Fortunately, there’s a solution: Portage allows per-package environment variable overrides via /etc/portage/env/. By putting some monkey patching code in the right place, we can override a function inside of all subsequent hplip ebuilds to automagically remove the ugly file. Create the right directory:

sudo mkdir -p /etc/portage/env/net-print

Then, add my monkey patch code to it:

sudo vim /etc/portage/env/net-print/hplip
if ( ! type -t original_src_install >/dev/null) && (type -t src_install >/dev/null); then
        eval "$(echo 'original_src_install()'; declare -f src_install | tail -n +2)"
        src_install() {
                original_src_install
                rm -f "${D}"/etc/xdg/autostart/hplip-systray.desktop || die
        }
fi

Finally, re-emerge hplip, and it should install without the autostart file. Yes, this is one ugly bash-ism, but it seems to do the job. Any suggestions would be appreciated.


Update: A reader below has noted that a far superior way of doing this is to just put

INSTALL_MASK="/etc/xdg/autostart/hplip-systray.desktop $INSTALL_MASK"

inside of /etc/portage/env/net-print/hplip, without needing to do the monkey patching above. INSTALL_MASK is a great feature, one that is not highlighted very much at all in the documentation. The most official mention of it I could find is in make.conf‘s man page:

       INSTALL_MASK = [space delimited list of file names]
              Use this variable if you want  to  selectively  prevent  certain
              files  from  being copied into your file system tree.  This does
              not work on symlinks, but only on actual files.  Useful  if  you
              wish  to  filter  out  files  like  HACKING.gz  and TODO.gz. The
              INSTALL_MASK is processed just before a package is merged.  Also
              supported  is  a  PKG_INSTALL_MASK variable that behaves exactly
              like INSTALL_MASK except that it is processed just  before  cre‐
              ation of a binary package.

Internally in misc-functions.sh, it does essentially the same thing as my monkey patch:

install_mask() {
	local root="$1"
	shift
	local install_mask="$*"
 
	# we don't want globbing for initial expansion, but afterwards, we do
	local shopts=$-
	set -o noglob
	for no_inst in ${install_mask}; do
		set +o noglob
		quiet_mode || einfo "Removing ${no_inst}"
		# normal stuff
		rm -Rf "${root}"/${no_inst} >&/dev/null
 
		# we also need to handle globs (*.a, *.h, etc)
		find "${root}" \( -path "${no_inst}" -or -name "${no_inst}" \) \
			-exec rm -fR {} \; >/dev/null 2>&1
	done
	# set everything back the way we found it
	set +o noglob
	set -${shopts}
}
October 31, 2011 · [Print]

6 Comments to “Monkey Patching Ugly Ebuilds — Disabling HPLIP’s Autostart”

  1. bearsh says:

    why you don’t use INSTALL_MASK? seems much easier for me then creating a ‘error prone’ bash sript. simply put INSTALL_MASK=”/etc/xdg/autostart/hplip-systray.desktop $INSTALL_MASK” in /etc/portage/env/net-print/hplip

  2. Alec says:

    Or better yet, just add “Hidden=true” to /etc/xdg/autostart/hplip-systray.desktop ;)

    http://en.gentoo-wiki.com/wiki/Hide_the_HPLIP_system_tray_icon

Leave a Reply