Remove and commit a composer dependency in vendor/

Reverting a composer dependency addition directly via ‘Revert Change’ from gerrit would break composer, as we experienced after merging The patch was to revert Plancake dependency due to compatibility issues in HHVM. I was un-aware of the fact that removing a dependency from composer.json would actually remove the dependency references from the vendor/ directory. Summing up – the correct way of producing a removal of a composer dependency would be:

  1. Remove the dependency from composer.json
  2. run composer update
  3. git add – -all
  4. git commit

A backport to an earlier branch can be produced with the following steps:

git pull --rebase
git checkout -b 'backportTo15' orgin/wmf/1.25wmf15
vi composer.json //remove dependecny
composer update
git add --all
git commt

If you screw up your backport in between – this would be an easy fix :

cd vendor
git pull --rebase
git review -d <change_id>
git checkout origin/wmf/1.25wmf15 . // would reset all files to wmf/1.25wmf15
vi composer.json // and remove the un-wanted dependency
composer update
git add --all 
git commit --amend
git review -R

Some moments from wikimedia-dev 🙂
[17:09:38] tonythomas: You’re meant to get composer to update itself. Otherwise it makes a huge mess.
[17:11:28] tonythomas: Yeah, composer and git aren’t friends. 😦

MediaWiki Unit Tests : Truncating table after each test

Writing PHP unit tests for the BounceHandler extension to prune old Bounce Records, I got into a situation where I had to truncate the ‘bounce_records’ and ‘user’ table after each single test. You would want the same when the test manipulates part of your table – and you dont want those changes to show up in your next test. Initially, I did this by manually truncating rows in both the table, but later I came across the use of

$this->tablesUsed = array( ‘table_name1’, ‘table_name2’ );

Implemented by :

class DoSomethingTest extends MediaWikiTestCase {
	protected function setUp() {
		// Your test initialization code here
		$this->tablesUsed = array( 'tableName' );

This would truncate ‘tableName’ table after each test ! Yay.
protected $tablesUsed = array(); is declared in MediaWikiTestCase.php[1] and its contents truncated after each test run !

[Ref : ]

[MW]$wgExtensionFunctions : Run a function when an extension is evoked

Working further with making the BounceHandler extension more production friendly – we came up with a scenario in which I wanted some of the extension global variables to take values from a MediaWiki global variable. It would’ve looked like $myExtensionGlobal = $mwGlobal – which looks weird.
Thanks to Hoo( WMDE ), I got introduced to $wgExtensionFunctions[] [1]

You need to run a function once your extension gets loaded. In my case, I want to check if $wgFoo ( which defaults to null ) was set in the original myExtension.php and if not – set it to the MW global – $wgBar
in your myExtension.php

$wgFoo = null;
$wgExtensionFunctions[] = function() {
	global $wgBar;
	$wgFoo = $wgFoo ? : $wgBar;

This would introduce a nameless function which would do our required manipulations.
You can even make it a named function as in :

$wgExtensionFunctions[] = &amp;quot;myFunction&amp;quot;;
function myFunction() {
         // Code your task

Hope it help someone ! Happy Hacking 🙂

MediaWiki PHP unit tests : Reading contents from a file ( @dataProvider )

While writing php unit tests for the BounceHandler extension, I came across a scenario in which I had to read contents from a text file and feed that to the test function as a variable. With the dataProvider functions it was solved simple.

* function testProcessTextfile( $foo ) function requires $foo to be read from a file from bar/foo.txt

In the class extending ApiTestCase give :

public static function provideFoo() {
	$foo = file_get_contents( __DIR__ .'/bar/foo.txt' );
	return array (
		array ( $foo )

* @dataProvider provideFoo
* @param $foo
function testProcessTextfile( $foo ) {
	//code to process $foo

That would do ! Happy hacking!
PS: Please note that the following wont work without the correct function comments and headers 🙂