Setting up a kickass development environment on Windows

Published on Jul 22, 2011 by Pim Elshoff

News #Jenkins #Ant #PHPUnit #Quality Assurance #PHP #Wamp #Pear #DocBlox #CodeSniffer

Recently I have become quite interested in quality assurance. Not that many things are going wrong for me, but I’d really like to be more certain about the quality of my work. I’ve used some tools to help me achieve just that. In less than two hours you can set up your workspace and have the living daylights automated out of you!

We will be using the following tools:

  • A DVCS, either
    • Git and GitHub
    • Mercurial, TortoiseHg and Kiln
    • Wamp
    • Pear
    • An assortment of pear tools, many of which by Sebastian Bergmann
      • PHPUnit
      • PHP_CodeCoverage
      • PHP_CodeSniffer
      • DocBlox
      • Ant
      • Jenkins

Why?

A good programmer is a lazy programmer. By setting up an automated environment that does the menial, boring stuff for you, you create more time for yourself to shine in what you are oh so good and getting better at.

I will not go into the merits of the various tools here, because this article is about getting it done. Still, here is a short intro on some of them.

The Version Control System (or: Source Code Management) holds your code. All of it. Everything that you’ve ever written and entered into it. A Distributed VCS is moar kickass and GitHub and Kiln can even put it on the net for you (even though GitHub requires you to open source your free account). I hope you already know about SCM’s, but if you don’t, read up and start using them for all your work asap.

Wamp installs Apache, PHP, MySQL and XDebug  on your machine and does it well. No head ache – it just works. Results!

Pear is a PHP tool that allows you to install PHP components, packages and tools. We need tools. What exactly all the tools do for us we’ll get into some other time. You can find out a lot by Googling them.

Ok here starts the magic. We use ant to create a ‘build’ of our project. A build is a set of products that can be generated from the source code. For a lot of languages that would be executable software, but for PHP the source code is pretty near executable. No, what we’re interested in are reports. We use Ant to call all the tools we installed, so that they can produce nifty XML, HTML and CSV files with all sorts of information about our code. Ant is our build automation tool.

Jenkins Timeline showing my progress Jenkins is the open source version of Hudson. It is a Continuous Integration tool that Sun released  when it was acquired by Oracle. Upon installation it will give you a nice web interface that you can use to navigate amongst the various jobs you have set up. Jobs? Jobs sounds like builds. We use Jenkins to automate our builds. We can set Jenkins to do a build with the push of a button, or every 10 minutes, or to check our VCS every 10 minutes or even to keep an eye on our GitHub accounts. The Jenkins web interface can understand the reports that Ant had the tools generate for us and shows us cool graphs. I don’t know about you, but I really like graphs. Like this one.

How?

1. Install Version Control

Download and install the DVCS of your likings:

There isn’t a lot to this. Just install it, we’ll get to using it later. If you’re familiar with SCM’s; basically any will do. At work I’m using SVN and TortoiseSVN.

2. Set up a local webserver

Go to http://www.wampserver.com/ and download the latest wamp. As of recent, wamp already includes XDebug, a debugging extension for PHP. Install Wamp and please leave it at c:wamp. This tutorial is difficult enough without you messing up my filepaths!

3. Go PEARs deep!

This one was daunting to me the first time, but actually didn’t turn out to be that hard. Follow this excellent instruction and you will be home free. Stop at the doctrine example; we are lazy and once we have pear installed we have everything we need.

If you get errors when starting up go-pear.bat, try downloading the latest pear phar. Just overwrite c:wampbinphpphp3.X.Xpeargo-pear.phar and try starting go-pear.bat again.

Open a terminal and run the command pear. It should give you a list of options and definitely not some error.

Make sure you edit both your php.ini files to add pear to include_path and to set the memory_limit to at least 1024mb. You can find them in c:/wamp/bin/apache/apache2.X.X/bin and c:/wamp/bin/php/php5.X.X.

4. PHP Tools

Aren’t we all?

Ahem. Open a terminal and execute the following commands:

pear channel-discover pear.pdepend.org
pear channel-discover pear.phpmd.org
pear channel-discover pear.phpunit.de
pear channel-discover components.ez.no
pear channel-discover pear.symfony-project.com
pear channel-discover pear.docblox-project.org

pear install pdepend/PHP_Depend
pear install phpmd/PHP_PMD
pear install phpunit/phpcpd
pear install phpunit/phploc
pear install PHP_CodeSniffer
pear install --alldeps phpunit/PHP_CodeBrowser
pear install --alldeps phpunit/PHPUnit
pear install –-alldeps docblox/DocBlox
pear install phpunit/ppw

This will install the tools we will use. Courtesy of http://jenkins-php.org/. I swapped out PHPDocumentor for DocBlox, because PhpDoc is old and slow and DocBlox is new and quick.

I had some serious trouble getting DocBlox and PHPUnit to work on Windows, because for some reason the Windows executables would not be installed. I solved this by downloading the complete packages and just copying them into the php folder (normally c:/wamp/bin/php/php5.X.X). Copy docblox.php to ./bin/docblox.php, copy docblox.bat, phpunit.bat and phpunit.php to ./.

Now the docblox.bat and phpunit.bat files need to be adjusted to the right path. The @something@ codes are normally replaced by the pear package, but since pear let us down and we do this thing manually, make sure docblox.bat and phpunit.bat look something like this. In fact, only this should be enough.

"C:/wamp/bin/php/php5.X.X/php.exe" "C:/wamp/bin/php/php5.X.X/bin/docblox.php" %*

And

"C:/wamp/bin/php/php5.X.X/php.exe" "C:/wamp/bin/php/php5.X.X/phpunit.php" %*

Try out if these work! Open a cmd and execute these commands:

pdepend
phpmd
phpcpd
phploc
phpcs
phpcb
phpunit
docblox
ppw

If they all execute, everything is a-ok! No mind if the apps themselves provide error messages, just make sure they execute. If either one fails, recheck the paths. Good luck…

5. Ant

Installing Ant is weird for us windows users. Download it, unzip it to a folder and add some environment variables. I guess it’s not too weird, but still. You can download Ant here (look closely, it’s a dreadful page) and find the installation gotcha’s here (mind the ‘setup’ part). Ant requires Java. In the odd chance you don’t have Java installed, Google it. Go on, Google it. Ok, fine.

Ant may provide a warning that you have not installed ‘tools.jar’. It has not affected me negatively, but this message can be discarded by using a JDK rather than an SDK version of Java.

I installed Ant in C:/Program Files(X86)/Ant.

6. Your butler for tonight, sir

Jenkins is available for download at http://jenkins-ci.org/. Install it and watch it install again, but then from a browser pov. Once you have Jenkins running, configure it to use your Ant. Not aunt, Ant!

Go to manage Jenkins, go to configuration, go to Ant, type in a recognizable name, uncheck the ‘auto-install’ checkbox and add the path to ANT_HOME.

Next, Jenkins requires a list of plugins to be able to deal with the PHP tools. Again, courtesy of http://jenkins-php.org/:

  • Checkstyle (for processing PHP_CodeSniffer logfiles in Checkstyle format)
  • Clover PHP (for processing PHPUnit code coverage xml output)
  • DRY (for processing phpcpd logfiles in PMD-CPD format)
  • HTML Publisher (for publishing the PHPUnit code coverage report, for instance)
  • JDepend (for processing PHP_Depend logfiles in JDepend format)
  • Plot (for processing phploc CSV output)
  • PMD (for processing PHPMD logfiles in PMD format)
  • SetEnv (for adding the path to pear in Windows)
  • Violations (for processing various logfiles)
  • xUnit (for processing PHPUnit logfiles in JUnit format)

Just ctrl+f these, check them and save your settings. Jenkins will take some time to reload and, in my case, hang on the DRY plugin. Just let it run for a while and refresh the browser window after.

If your project is of considerable size, make sure to go to the Jenkins folder and open Jenkins.xml (c:Program FilesJenkinsjenkins.xml). Here you can see the service definition for Jenkins and you can see the parameter –Xmx256mb. This is the max amount of memory that the JVM can load in. Set it to the amount you think you need (I set it to –Xmx1024mb). The PHP tools and the Jenkins analyzer are run serially.

7. Start a project!

Take a folder for your code. Mine is d:/Home/Pelshoff/Code. Take a dir for your project. Mine is d:/Home/Pelshoff/Code/MyProject.

Every project will have about the following folders: src, tests and build. Use ‘em, don’t be strong headed now, we’ve come so far! Your code goes into src, your unit tests go into tests and whatever products you will want built go into build.

For example, were I to start a project called ‘Awesome’, my folder structure could be something like this (using neat PHP vendor and project namespaces):

d:/Home/Pelshoff/Code/Awesome/build
d:/Home/Pelshoff/Code/Awesome/src/Pelshoff/Awesome/<code goes here>
d:/Home/Pelshoff/Code/Awesome/tests/Pelshoff/Awesome/<tests go here>

Now it’s time to create a SCM repository.

Command line

Navigate to your project folder and… oh go read a tutorial on that!

Gui

Open explorer, navigate to your vendor folder, right-click your project folder and see the new options either git or mercurial has given you.

TortoiseHg: create repository here

Git: Gui here

Once you’ve started a repository you will find that the folder and file icons have small indicators with them, showing whether files are unchanged, changed, newly added, unknown or otherwise interesting from a SCM point of view. If you’ve got some code, commit it.

8. Create your MyFirstBuildFile

Open a terminal and navigate to your project folder. Mine is d:/Home/Pelshoff/Code/MyProject, remember? Execute the command:

ppw --source src --tests tests --name ExampleProject

Now you have a build file, but it’s a bit dirty. It’s written for (feel the temperature drop) Linux! Sadly, the tool execution don’t work too well under Windows, nor does writing output to /dev/null. Open the newly created build.xml file and

  1. Add the following lines to the top, right above the first ‘property’:
    <property environment="env"/>
    <property name="peardir" value="${env.PHP_PEAR_BIN_DIR}"/>
  2. Prefix every PHP tool call with ${peardir}/ and suffix it with .bat.  For example,
    <exec executable="phpunit"> becomes
    <exec executable="${peardir}/phpunit.bat">
  3. Windows cannot really handle filepaths with spaces in them, so find every instance of ${build}, ${source}, ${basedir}  and every other filepath and escape them with single quotes. For example,
    <arg line="-d ${source} -t ${basedir}/build/api" /> becomes
    <arg line="-d ‘${source}’ -t '${basedir}/build/api'" />
  4. Switch the phpdoc call for docblox. Your docblox arguments could look like this:
    -d ${source} -t '${basedir}/build/api' --title MyProject

Save your build file and we have taken another hurdle! For funzies, here is one of my buildfiles.

When you’re working on a project that should only partly be built, mind that the tools have varying ignore parameters:

  • Pdepend
    --ignore='Path/'
  • Phpmd
    --exclude *path*
  • Phpcpd
    --exclude '${source}/path'
  • Phploc
    --exclude '${source}/path'
  • Phpcs
    --ignore=*path*
  • Docblox
    --ignore 'path/'
  • Phpcb
    --ignore '${basedir}/src/path/'

I wouldn’t dare say these are the only ones that work and I wouldn’t even dare guarantee they work everywhere, but they do work on several windows 7 and vista machines ranging wamp with php 5.3.0 to php 5.3.5. I also wouldn’t dare say this cost me a lot of time to figure out, but it did.

10. Install the PHP-Template job for Jenkins

Jenkins jobs can be built taking another, previously existing job as a template. Sebastian Bergmann has made such a template job which is available at http://github.com/sebastianbergmann/php-jenkins-template. Download it and put the files from the zip into C:/Program Files(x86?)/Jenkins/JobsPHPTemplate.

11. Create a job in Jenkins

Reload Jenkins by going to ‘Manage Jenkins’ then ‘Reload Configuration from Disk’. Go to new job and enter a name and make sure you ‘Copy existing Job’ PHPTemplate (this field is case-sensitive).

When the job is created you will be presented with its configuration.

  • Edit the ‘Description’ to provide your project name (this description will load cool graphs).
  • Uncheck the ‘Disable Build’ check.
  • Add your SCM information.
  • Click ‘Set environment variables’ and enter the following information:
    PHP_PEAR_BIN_DIR=C:/wamp/bin/php/php5.X.X
    where php5.X.X is replaced by your actual php version, of course. Mind that the slashes face right!

We need Jenkins to set ‘environment variables’ for us, because while ant can normally find them out it can’t do so when covered by Jenkins. We could of course have just set the proper path in our buildfile, but then our buildfile would be machine dependent. The SetEnv plugin allows us to simulate environment variables so we can still use a machine independent buildfile.

  • Select your own specific Ant version. Jenkins won’t find the default ‘ant.bat’ file, or at least it didn’t for me.

Now there are a lot of ‘post-build’ actions, but they are already filled in. This is it, our build setup should be complete. Save your config.

12. There is no step 12. We’re done!

Click ‘Build now’ to test it. I hope everything works out for you and if it doesn’t please let me know how I can upgrade my tutorial.

Conclusion

This tool has helped me some at work, where we started using it a week or so ago. I have it setup to build every day at 12:30 and I have seen the violations and warnings count go down already. We have our own specific codestyle at Crowd Surfing, so I’m currently working on expanding our CodeSniffer standard as well.

At home, for my own projects, I have an almost default setup running. At the end you will find some screenshots of the Jenkins dashboard.

Please let me know if this article has been helpful for you. If you run into any problems, have any questions or any other feedback, please contact me. Good luck in setting up your own kickass development environment!

A screenshot of Jenkins
Pim Elshoff

About the author

Pim has been working the web since 2004! Read more about Pim

Comment(s)

  1. Surt

    Surt said:

    Great!

    I'll try it asap.
    01:29, 27 July 2011
  2. Pim Elshoff

    Pim Elshoff said:

    Good luck, let me know how it goes. 18:46, 27 July 2011
  3. Enrique

    Enrique said:

    I usually develop custom web apps projects with codeigniter. I use SVN, xampp and firebug, just that...

    Which GREAT benefits could I get using all the other tools and what does "build" do/mean with php related projects?

    Also, I've been looking a way to copy then erase automatically all *svn files from my project dir before uploading final app to ftp. Can any of those tools help me to do that?

    Thanks, great article
    21:29, 27 July 2011
  4. Pim Elshoff

    Pim Elshoff said:

    SVN and xampp are great! Kudo's for using an SCM. It's a big plus for a developer. Firebug is great for debugging CSS and for ad-hoc debugging JS.

    What really makes these tools great is that it's a one-time setup. Just run the tools and you get all the info you need. There's stuff in there on codestyle adherence and 'messy coding', information on the quality of your work from an OOP perspective (cyclomatic complexity et al.) and there is automated testing with PHPUnit. I will go into the benefits of these tools more deeply in an upcoming article. In the meanwhile I can direct you to Sebastian Bergmann and Martin Fowler for fantastic information on Quality Assurance and Continuous Integration.

    As for 'erasing the *svn' files; Yes, there is a way to have these tools do that for you. The ant ftp task ignores the .svn folders by default. You may also use the SVN 'export' function, though. It's not really about erasing svn files as much as it is about getting an unversioned version of your work :) Git and Mercurial don't put a .git and .hg folder everywhere btw; they only place their info in the upmost folder.

    Thanks for your feedback!
    18:22, 28 July 2011
  5. Chris Reed

    Chris Reed said:

    As usual, PEAR doesnt' work, even with the instructions posted (not surprising, it's PEAR). I found this link (http://stackoverflow.com/questions/4717547/cant-install-pear-on-windows-7-structures-graph-error) to fix the errors that do pop up that prevent anything being installed or upgrading. 06:49, 06 August 2011
  6. Chris Reed

    Chris Reed said:

    Also ran into the same issue with PHPUnit and DoxBloc. Lots of dependency hell with those two for some reason 07:09, 06 August 2011
  7. Pim Elshoff

    Pim Elshoff said:

    Yes it's terrible on windows, but good job on pulling through! Did you manage to get the entire setup working for you? If so, what do you think of it? 09:32, 06 August 2011
  8. Andrew

    Andrew said:

    For those with problems on windows with (structures-graph) - You simply need to manually download the structures package from pear.php.net (such as Structures_Graph-1.0.4.tgz) and manually extract it to your pear folder.
    Job done :-)
    11:09, 10 August 2011
  9. david v

    david v said:

    Hi there,

    I had the following issues when installing pear components:

    C:\Windows\system32>pear install --alldeps phpunit/PHPUnit
    phpunit/PHPUnit is already installed and is the same as the released version 3.5
    .15
    install failed

    C:\Windows\system32>pear install –-alldeps docblox/DocBlox
    Failed to download docblox/DocBlox within preferred state "stable", latest relea
    se is version 0.15.1, stability "beta", use "channel://pear.docblox-project.org/
    DocBlox-0.15.1" to install
    parsePackageName(): invalid package name "û" in "û-alldeps"
    invalid package name/package file "û-alldeps"
    install failed

    C:\Windows\system32>pear install PEAR_Frontend_Web
    Failed to download pear/PEAR_Frontend_Web within preferred state "stable", lates
    t release is version 0.7.5, stability "beta", use "channel://pear.php.net/PEAR_F
    rontend_Web-0.7.5" to install
    install failed

    Any workarounds?
    09:17, 10 October 2011
  10. Pim Elshoff

    Pim Elshoff said:

    Hi David,

    Sorry I hadn't responded sooner; I've been very busy. Packages you have already installed are fine; you may try updating them but PhpUnit 3.5 should work fine for you. It integrates with decent IDE's such as netbeans and phpstorm as well :)

    As for installing 'unstable' packages; some packages simply don't have a stable release yet and DocBlox is indeed one of them. What you could do is to set your 'preferred state' to beta, install the package and then reset the preferred state to stable:

    pear config-set preferred_state beta
    pear install docblox/DocBlox
    pear config-set preferred_state stable

    Does that help at all?
    19:57, 18 October 2011
  11. david v

    david v said:

    Hi Pim,

    I had tried your suggested method, the 2nd step failed with error:

    C:\Windows\System>pear install docblox/DocBlox

    No releases available for package "pear.docblox-project.org/DocBlox"
    install failed

    Any ideas?
    10:13, 19 October 2011

Trackbacks

No trackbacks yet

Leave a comment

All comments will be moderated

  Veld is verplicht
Captcha
  I'm terribly sorry that this is necessary and I appreciate the effort you are taking to post a comment!