Notify me when emerge is done

As a Gentoo user, I frequently install new software or update existing packages using emerge. Unlike binary package managers, building packages from source using emerge takes time, and I prefer running it inside a detached screen session, because (a) if I close the session it continues in the background and (b) it actually runs faster when it doesn't need to show all the compilation output in an X terminal.

This has an annoying side effect: I sometimes start a long update process and forget I did it. If things fail (or even if they succeed) I don't know about it.

Today, I solved this problem using notify-send, the libnotify binary client. I've created a short shell script wrapper to emerge which sends me a notification once emerge finishes, along with the original command line arguments and exit status code (0 = ok, failure otherwise):

CODE:
  1. #!/bin/sh
  2.  
  3. ARGS=$@
  4.  
  5. /usr/bin/emerge "$ARGS"
  6. STATUS=$?
  7. if [ "$STATUS" = "0" ]
  8. then
  9.         LEVEL="normal"
  10. else
  11.         LEVEL="critical"
  12. fi
  13.  
  14. /usr/bin/notify-send --expire-time=0 --urgency=$LEVEL "emerge finished" "Exit Code: $STATUS
  15. Emerge args: $ARGS"

If you save this code in a file named emerge-notify (and of course remember to chmod +x this file) you could then do this (from a GNOME terminal or any other X terminal):

CODE:
  1. $ ./emerge-notify -puD world

And you'll get a nice notification when it's done:

"emerge finished" notification

Of course, you need libnotify the notify-send binary and dbus for this.

PHP Error Reporting Levels - WTF is 6134?

In PHP, the error reporting level (whether errors go to the log or to the screen or whatever) is determinded by the error_reporting INI directive (or at runtime using the error_reporting() function). Both take an integer as their value - and usually this integer is represented by error level constants like E_ALL, E_STRICT or E_USER_WARNING.

So in order to set the error reporting to anything but notices and strict errors, you would set something like this in php.ini:

CODE:
  1. error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT

(actually, E_ALL does not really include E_STRICT but I put it here just to be more explicit)

This is actually great - one of the more easy to use and understand APIs in my opinion (yeah, I really like bitwise operations).

However, what I really hate is that sometimes I need to work with the integer value of the error reporting level (like 1 for E_ERROR or 84 for E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR) and it's very hard for me to remember what arbitrary numbers like 6134 mean.

So, today I wrote this tiny CLI script that helps me understand what an arbitrary error_reporting level integer might mean:

CODE:
  1. <?php
  2.  
  3. $errorLevels = array(
  4.         'E_COMPILE_ERROR'     => E_COMPILE_ERROR,
  5.         'E_COMPILE_WARNING'   => E_COMPILE_WARNING,
  6.         'E_CORE_ERROR'        => E_CORE_ERROR,
  7.         'E_CORE_WARNING'      => E_CORE_WARNING,
  8.         'E_ERROR'             => E_ERROR,
  9.         'E_NOTICE'            => E_NOTICE,
  10.         'E_PARSE'             => E_PARSE,
  11.         'E_RECOVERABLE_ERROR' => E_RECOVERABLE_ERROR,
  12.         'E_STRICT'            => E_STRICT,
  13.         'E_USER_ERROR'        => E_USER_ERROR,
  14.         'E_USER_NOTICE'       => E_USER_NOTICE,
  15.         'E_USER_WARNING'      => E_USER_WARNING,
  16.         'E_WARNING'           => E_WARNING,
  17. );
  18.  
  19. if (! isset($_SERVER['argv'][1])) {
  20.         fprintf(STDERR, "Usage: {$_SERVER['argv'][0]} <error_level>\n" .
  21.                         "  Where <error_level> is a PHP error reporting level\n");
  22.         exit(1);
  23. }
  24.  
  25. $level = $_SERVER['argv'][1];
  26.  
  27. echo "Error level $level includes:\n";
  28. foreach ($errorLevels as $k => $v) {
  29.         if ($level & $v) echo "\t $k \n";
  30. }
  31.  
  32. echo "\n";

To use, just run the script with a single value parameter, like so:

CODE:
  1. shahar.e@wintergreen ~ $ php error_level.php 6134
  2. Error level 6134 includes:
  3.      E_COMPILE_ERROR
  4.      E_COMPILE_WARNING
  5.      E_CORE_ERROR
  6.      E_CORE_WARNING
  7.      E_PARSE
  8.      E_RECOVERABLE_ERROR
  9.      E_USER_ERROR
  10.      E_USER_NOTICE
  11.      E_USER_WARNING
  12.      E_WARNING

Enjoy!