Using Grunt to test WordPress Upgrade changes

During the final moments of a WordPress release development cycle I was asked a very simple question:

How do I test the changes to src/wp-admin/includes/update-core.php before they’re committed to trunk?

One method that others have resorted to is to build a custom WordPress release zip and hack WordPress to always install from that custom zip file – It’s not hard to do that, but it’s a real pain when your development workflow includes testing things time and time again.  [note: I’ve used this method in the past, before Grunt was “a thing”]

So, here’s my current solution: Use grunt build and hit Update, something we all use already, coupled with WordPress’s own update routines!

The way that I do it, is that I apply the patch to /src/, and then alter class-wp-upgrader.php to use the local copy of update-core.php instead of the one from the zip file it’ll download, and then just hit Update on the dashboard.

This takes very little effort to pull off – below is an example of the code changes needed to cause it to abort a update early on with a custom message, all that’s left to do is to run grunt build and hit the update button! – Just make sure you’re in /build/ rather than /src/, as it could quickly lead to custom code going missing.. I know this from experience!

Index: src/wp-admin/includes/class-wp-upgrader.php
==================================================================
@@ class Core_Upgrader extends WP_Upgrader
 $working_dir = $this->unpack_package( $download );
 if ( is_wp_error($working_dir) )
 	return $working_dir;

 // Copy update-core.php from the new version into place.
-if ( !$wp_filesystem->copy($working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true) ) {
+if ( false && !$wp_filesystem->copy($working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true) ) {
 	$wp_filesystem->delete($working_dir, true);
 	return new WP_Error( 'copy_failed_for_update_core_file', __( 'The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.' ), 'wp-admin/includes/update-core.php' );
 }
 $wp_filesystem->chmod($wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE);

 require_once( ABSPATH . 'wp-admin/includes/update-core.php' );

Index: src/wp-admin/includes/update-core.php
==================================================================
  * @param string $from New release unzipped path.
  * @param string $to   Path to old WordPress installation.
  * @return WP_Error|null WP_Error on failure, null on success.
  */
 function update_core($from, $to) {
 	global $wp_filesystem, $_old_files, $_new_bundled_files, $wpdb;

+	// Demo code to show that this process works
+	echo "Hi! This is text to confirm that I'm using a custom update-core.php file during the update!";
+	die();
+
 	@set_time_limit( 300 );

A few frequently asked questions that have come up in the past with this method:

  1. Question: It’s still downloading the zip file from the internet though!
    Answer: Yes, it does. However my internet connections are usually fast enough that this isn’t a problem.
  2. Question: What if there’s other alterations needed in other update related files?
    Answer: It doesn’t actually matter, update-core.php is the only file from the zip that’s used during update, all the other files (WP_Upgrader / WP_Filesystem / etc) use what’s installed, they’re only overwritten once the update commences using the old code.
  3. Question: How do I stop it from redirecting after the update?
    Answer: When you find out, let me know!  I’ve resorted to simply adding a die(); after the debug code I’m using.
  4. Question: Why isn’t there a grunt task to build the WordPress zips?
    Answer: Haven’t needed one yet I guess? Why don’t you submit a patch on Trac for it? :)

Twenty Eleven Theme Colour Palette

As a follow up to my previous post: WordPress 3.2 Admin Colour Palette I was asked if I could do a Twenty Eleven version. See the previous post for the script used.

Standard “Light” colour scheme

#e5e5e5
#000000
#f7f7f7
#efefef
#444444
#0a0a0a
#ffffff
#555555
#aaaaaa
#d3d3d3
#575757
#f6f6f6
#999999
#777777
#3c3c3c
#252525
#f9f9f9
#666666
#222222
#cccccc
#e2e2e2
#dddddd
#373737
#fafafa
#f4f4f4
#eeeeee
#bbbbbb
#111111
#888888
#7a7a7a
#e0e6e8
#bfddf3
#fff9c0
#29628d
#ff4b33
#1982d1
#0861a5
#bd3500

Alternate “Dark” theme

Just a note here, Due to TwentyEleven’s structure, some of the colours in the above light theme will be used as part of this colour scheme, this is just for visual information purposes.

#282828
#888888
#060606
#444444
#000000
#2c2c2c
#aaaaaa
#555555
#090909
#a8a8a8
#959595
#c3c3c3
#777777
#111111
#1d1d1d
#242424
#0b0b0b
#ffffff
#999999
#333333
#bbbbbb
#0f0f0f
#dddddd
#222222
#383838
#272727
#cccccc
#0a0a0a
#858585
#eeeeee
#42caff
#40220c
#00b4cc
#00063f

Opera IRC Auto-reconnect

So, we all love using Opera as our browser, right? How many of you use IRC in Opera too? *cricket chirping*

Ok, Well, I do, and unfortunately Opera doesn’t support IRC auto-reconnection, this is rather annoying when you consider that hibernating the laptop will cause IRC to disconnect, and it doesn’t re-connect upon resuming windows.

“Simple, Just click Connect every time you resume!” yes well, I forget and can often not be on IRC for hours because of that.

So a solution. Add the IRC server to your speed dial! 

That might sound a bit strange, but it works, Simply add irc://irc.freenode.net/ (or your favourite IRC server) to your speed dial, sure enough, when you open a new tab next time you use Opera, the icon will refresh, the refresh triggers a re-connect if there isn’t already a connection! (Make sure you also have the channels you use in your connections outgoing-commands section)

It’s not perfect, but it’s doing the job for me :)

WordPress 3.2 Admin Colour Palette

So a ticket popped up on trac, mentioning the Gray colour scheme example colours were out of date, gave me a quick idea to make a script to make a colour palette of the colour schemes (ie. All colours used in the colour css file), so here we have it:

Fresh – Gray

#e9e9e9
#f5f5f5
#c3c3c3
#ededed
#909090
#a0a0a0
#ffffff
#d7d7d7
#f2f2f2
#dadada
#aaaaaa
#ebebeb
#555555
#b2b2b2
#888888
#e7e7e7
#c0c0c0
#606060
#d5d5d5
#fbfbfb
#c1c1c1
#d3d3d3
#e3e3e3
#e5e5e5
#444444
#cfcfcf
#e1e1e1
#6d6d6d
#bbbbbb
#f4f4f4
#666666
#dddddd
#e8e8e8
#9a9a9a
#fcfcfc
#000000
#ececec
#101010
#f9f9f9
#222222
#808080
#cccccc
#f1f1f1
#dfdfdf
#eeeeee
#eaeaea
#464646
#333333
#777777
#999999
#ebeaeb
#f0f6fb
#eaf2fa
#eaf3fa
#ededff
#ffebe8
#e4f2fd
#fffbe4
#ffffe0
#b6bdd2
#ddffdd
#ffdddd
#cfe1ef
#cee1ef
#ccf3fa
#b8d3e2
#fffbcc
#f0f0b8
#9fd0d5
#9999dd
#ffa0a0
#ff9999
#99ff99
#557799
#ffb78c
#ffec8b
#c3ff88
#ff6666
#264761
#e6db55
#448abd
#f04040
#cc4433
#ff853c
#298cba
#21759b
#13455b
#d54e21
#8dff1c
#0a246a
#bc0b0b
#0000ff
#ffcc00
#cc0000
#dd0000
#006505
#d98500
#ff0000

Classic – Blue

#e9e9e9
#606060
#aaaaaa
#ebebeb
#f2f2f2
#464646
#dddddd
#e8e8e8
#9a9a9a
#dadada
#e5e5e5
#444444
#b2b2b2
#c9c9c9
#f5f5f5
#c3c3c3
#f4f4f4
#fcfcfc
#888888
#555555
#d7d7d7
#ffffff
#101010
#bbbbbb
#d5d5d5
#e7e7e7
#000000
#666666
#222222
#cccccc
#c1c1c1
#f9f9f9
#808080
#333333
#eaeaea
#dfdfdf
#777777
#999999
#eeeeee
#c0c0c0
#f1f1f1
#d3d3d3
#ebeaeb
#f7fcfe
#f5fafd
#efede7
#f0f6fb
#eff8ff
#eaf3fa
#eaf2fa
#ededff
#ecf8fe
#ffebe8
#e4f2fd
#fffbe4
#d0dfe9
#cfdfe9
#bdccd5
#ffffe0
#d1e5ee
#b6bdd2
#ffdddd
#ddffdd
#cfe1ef
#cee1ef
#bed1dd
#b0c8d7
#ccf3fa
#b8d3e2
#fffbcc
#f0f0b8
#a0c3d5
#9fd0d5
#9999dd
#ffa0a0
#99ff99
#ff9999
#557799
#ffb78c
#ffec8b
#c3ff88
#5a8fad
#5589aa
#ff6666
#264761
#e6db55
#448abd
#f04040
#cc4433
#ff853c
#185069
#298cba
#174f69
#21759b
#13455b
#d54e21
#8dff1c
#0a246a
#bc0b0b
#ff0000
#ffcc00
#cc0000
#d98500
#dd0000
#0000ff
#006505

Script used

[php]
<?php
$file = ABSPATH . ‘wp-admin\\css\\colors-classic.dev.css’;
$file = escapeshellarg($file );

$in = shell_exec("grep -i -o -e #[0-9a-f]\\{3,6\\}\\b $file | uniq -i");

$in = str_replace(array(‘:’, ‘#’, ‘ ‘), ”, $in);

$in = explode("\n", $in);
$in = array_filter($in);

foreach ( $in as $i => $v ) {
if ( strlen($v) == 3 )
$in[$i] = $v[0] . $v[0] . $v[1] . $v[1] . $v[2] . $v[2];
}

$out = array();
foreach ( $in as $rgb ) {
$r = hexdec( substr($rgb, 0, 2) );
$g = hexdec( substr($rgb, 2, 2) );
$b = hexdec( substr($rgb, 4, 2) );
$hsl = rgb2hsl($r, $g, $b); // we’ll sort it by the Saturation
$out[ strtolower($rgb) ] = $hsl;
}

uasort($out, function($a, $b) {
return $a[1] > $b[1];
});

foreach ( $out as $c => $hsl ) {
$f = ($hsl[2] > 0.6 ) ? ‘000’ : ‘fff’;
echo "<div style=’background-color: #$c; color:#$f; width: 80px; height: 40px; display: inline-block;’>#$c</div>";
}

foreach ( $out as $c => $hsl ) {
$f = ($hsl[2] > 0.6 ) ? ‘000’ : ‘fff’;
echo htmlentities("<div style=’background-color: #$c; color:#$f; width: 80px; height: 40px; display: inline-block;’>#$c</div>") . ‘<br />’;
}

function rgb2hsl($r, $g, $b) {
$var_R = ($r / 255);
$var_G = ($g / 255);
$var_B = ($b / 255);

$var_Min = min($var_R, $var_G, $var_B);
$var_Max = max($var_R, $var_G, $var_B);
$del_Max = $var_Max – $var_Min;

$v = $var_Max;

if ($del_Max == 0) {
$h = 0;
$s = 0;
} else {
$s = $del_Max / $var_Max;

$del_R = ( ( ( $var_Max – $var_R ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
$del_G = ( ( ( $var_Max – $var_G ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
$del_B = ( ( ( $var_Max – $var_B ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;

if ($var_R == $var_Max) $h = $del_B – $del_G;
else if ($var_G == $var_Max) $h = ( 1 / 3 ) + $del_R – $del_B;
else if ($var_B == $var_Max) $h = ( 2 / 3 ) + $del_G – $del_R;

if ($h < 0) $h++;
if ($h > 1) $h–;
}

return array($h, $s, $v);
}
?>
[/php]

This post was edited to correct a few things, including sorting by the saturation of the colour rather than alphabetically.