Complete PHP Development Environment on OSX – Step 3: Subversion

On February 3, 2012, in Tutorials, by Born To Code Admins

Today it’ll be about Subversion.

What is Subversion?

Subversion is a versioning and revision control system used to keep different versions (duh) of all files for a given system. It’s written in C, runs on any plattform, and it has many advantages like the fact that almost all serious IDEs integrate with it.

At Subversion’s core we find a repository, the central location for data storage. The repository behaves pretty much like a filesystem, handling a basic hierarchy of files and directories. When talking about a central storage location, it becomes evident that if access to said share is allowed to multiple clients at the same time, we run the risk of having more than one client modifying the same file at the same time, and that when they save the changes only the last change will prevail. That’s where subversion comes in: it can remember each and every change made to the repository, and it allows clients to view the different versions of a given file, allowing us to identify who was the last one to modify a file, what are the changes applied to the file, etc.

Why should I use a versioning system like Subversion?

Since this is a pretty basic topic, those of you who already know why we should use a tool like subversion can go ahead and skip this section and go straight to the section titled Installation.

Ok, from the previous short introduction to subversion we can easily identify the fact that one of the main problems that arise when sharing files is “stepping on” somebody else’s changes. Joe and Susan download a copy of File A. Joe modifies the first paragraph, Susan modifies the second paragraph, Joe uploads the file back to the central file share and happily goes home to his white-picket-fence house in the suburbs to talk to his wife and play with his kid and his golden retriever. Five minutes later Susan uploads her file to the central file share and overwrites the changes made by Joe. Joe goes to the office the following day and cries.

To remediate this situation there’s the “lock-modify-unlock” method. Joe downloads his copy of the file, he locks it and he proceeds to modify it. Susan tries to download a copy but she can’t: the file is locked by Joe, so -at most- she can only download a read-only copy of the file. Joe uploads his copy to the central share and unlocks it. Susan can now download her copy, which happens to include Joe’s changes. Problem solved…Can we go home and sleep? No. This solution brings along a bunch of annoying issues:

-Joe goes home and forgets to upload his copy, and the file remains locked. Nobody can do anything until Joe unlocks the file again. Imagine if Joe goes on vacation, or if he got laid off.
-Locking files forces us to work sequentially. Maybe Joe needs to modify the first page of a document and Susan the last one, so there’s no reason for them to wait for each other.
-Inconsistency, repeat after me, inconsistency. Maybe Joe edits file A, Susan edits file B, and we are all happy thinking that they haven’t stepped on each other’s changes, but it could very easily turn out to be that file A now is not compatible with the changes introduced by Susan to file B, and/or the other way around. We must find another solution.

To overcome the aforementioned obstacle in the lock-modify-unlock method, we can make use of the “copy-modify-merge” paradigm. Under this method, Joe and Susan download their own copy of a given file, and go ahead and modify it. Joe modifies the first page and uploads his copy to the share, Susan modifies the last page and when she attempts to upload her copy, she’s notified that the file has been modified (by Joe) since she got her copy: now Susan can have her changes merged, and since they modified different pages, the changes are not overlapping so a new copy of the file containing all modifications is created.

Let’s look at what would happen if both Joe and Susan modify the first page of the document, effectively having overlapping changes: when Susan attempts to update her copy, she is notified of changes made by Joe that conflict with her own changes, she can see Joe’s copy in order to review the changes and compare them to her own, and she’ll be allowed to manually select the changes to be applied to the file.

Okay, enough of Joe and Susan. Let’s talk about developers. We got a dev team, everybody downloads a copy of the system and works on their own piece, they upload their copy, and if there are any conflicts they are resolved by manually selecting the changes. This brings:

-A team can work simultaneously, without developers having to wait for each other
-After producing a new version, if the build fails we can easily go back to previos versions
-When troubleshooting bugs, we can compare all changes made to the system to identify which change created the problem
-Developers can work on modules and features simultanously, without delaying other versions
-You can release bug fixes for a particular version, and keep working on the current one
-You can create different branches of your system
-…
-etc..

Installation

Okay, let’s see how we can install Subversion on OSX. We’ll need a Subversion repository, and a client.

Subversion Client (svn)
The standard OSX install comes with svn, but we can double check by issuing:

$ svn --version

we expect:

svn, version 1.6.5 (r38866)

Now we’ll set vi (or any other editor you’d like to use) as our editor for the svn client. We proceed to edit ~/profile and add the following line:

export SVN_EDITOR=/usr/bin/vi

Note: changes to ~/profile don’t get integrated until you launch a new shell or log out and back in (thanks m0ll)

Subversion Repository

You can install your own repository, or use a hosted service like Google code, Unfuddle, etc.
We are going to use Google Code, the project is www-borntocode-com (http://code.google.com/p/www-borntocode-com/), the steps are:

  1. Create the svn repository (you do this at the dashboard if you are using unfuddle.com) – in our case the URL is:
    http://www-borntocode-com.googlecode.com/svn/trunk/
  2. Add users and/or grant access to the repository (depends on the server)
  3. Check out the repository to our own local copy
    $ svn checkout svn checkout https://www-borntocode-com.googlecode.com/svn/trunk/ www-borntocode-com --username xxxxx

    We expect (any other number is fine):

    Checked out revision 1.

    It may prompt you for a username and password, it depends on the server’s security configuration

  4. Create the project structure (if it hasn’t been created yet):
    $ mkdir website
    $ mkdir website/trunk
    $ mkdir website/branches
    $ mkdir website/tags

    Here we can also add to svn>ignore what we only want to keep on our local copy, in other words, what we don’t want to have in the repository (e.g., .DS_Store files)

  5. Add whatever we have to the repository
    $ svn add *
    $ svn commit --message "project setup"

    We expect (any other number is fine):

    Committed revision 1.

Okay that was a long article. See you next time, we’ll be talking about Jenkins (previously known as Hudson).

See ya!


 

Complete PHP Development Environment on OSX – Step 2: Phing

On January 11, 2012, in Tutorials, by Born To Code Admins

Today’s menu: Phing.

What is Phing?

Phing is a project build system, similar to Ant. It’s written in PHP and one of its many advantages is that it integrates with PHPDocumentor, PHPLint, PHPUnit, et al. Phing will let us manage all aspects of our builds and deployments.

Why should I use Phing?

If you asked yourself this question, is probably because you’ve never deployed a complex system. When deploying projects that require implementing changes to different targets, it becomes progressively harder to remember, manage and control the execution of all the necessary steps needed to install the new version.

Phing facilitates the building and deployment process of your projects and eliminates repetitive tasks (and all the accompanying errors that come with them), which minimizes erroneous/bad builds. Phing provides SVN tasks, file manipulation, executes zip/unzip type actions, manages DB model deployment and, to top it off, it integrates with tools like PHPUnit.

Phing has a beautiful task called DbDeploy, that will facilitate the implementation of changes to our DB model when installing a new version or when rolling back, given that it manages the upgrade and downgrade scripts. Now our DB model can live in SVN. Cool, huh?

This time we won’t dive into the specifics of this particular aspect because we feel Dave Gardner did an excellent job writing about it.

Installation

Okay, let’s see how we can install Phing and make it part of our development environment.

$ sudo /Applications/MAMP/bin/php5/bin/pear channel-discover pear.phing.info
$ sudo /Applications/MAMP/bin/php5/bin/pear install phing/phing

Verify the installation:

$ /Applications/MAMP/bin/php5/bin/phing -version

We expect:

Phing 2.4.4

Once we’ve installed Phing, we must add the FileSync task (thanks Federico Cargnelutti!). For this we simply download FileSyncTask.php and save it to /Applications/MAMP/bin/php5/lib/php/phing/tasks/ext/.

Now we have to ad the information we would like to synchronize. To do this, first we make sure that we have SSH access:

$ ssh user@host

Then we edit build.properties, filling in with the values according to your environment:

sync.source.projectdir=/Users/USERNAME/bornToCode/workspace/www-borntocode-com/
sync.destination.projectdir=/home/USERNAME/stages/test/
sync.remote.host=www.borntocode.com
sync.remote.user=USERNAME
sync.destination.backupdir=backup/
sync.exclude.file=/Users/USERNAME/bornToCode/workspace/www-borntocode-com/sync.exclude
sync.verbose=false

All that’s left is launching the build with Phing:

$ phing sync

We aren’t expecting any output, just make sure there aren’t any errors.

We hope you enjoy using Phing. We’ll see you next time when we talk about Subversion.


 

Complete PHP Development Environment on OSX – Step 1: PHPUnit

On January 11, 2012, in Tutorials, by Born To Code Admins

Our previous post in this article series left us with an environment ready to start installing all the tools that will facilitate a complete development environment on OS X. Today is all about the first step, and we’ll install PHPUnit, an Unit Testing framework.

What’s Unit Testing?
Unit Testing is a method that can be applied to determine if a particular unit of code meets specified requirements and specifications and to see if it’s suitable to be used and included in a system. So…what’s a unit? We define a unit as the smallest component of a system that does useful work and where tests can be applied to.

Basically, the idea is that whenever a software requirements specification is received, we start by writing a small test program that the unit needs to pass to satisfy said requirement. Then we proceed to execute the test and verify that the test fails, which is kind of expected ;) . Warning: if the test execution doesn’t fail, it’s it could be because the requirement has already been implemented, or…welll…the test program is wrong. It could also mean that we’ve reached the highest level of programming Zen and the solution has manifested itself automagically, in which case we proceed to buy a lottery ticket and self-proclaim champions of the universe.

Ok, we passed the first test: we executed it and it fails…excellent, now we need to implement a solution (who knew!) and execute the test again. The unit can also be considered ready for the system if the test has been passed. Pretty simple, isn’t it?

At first this may seem like a waste of time, but it really isn’t: you end up producing high quality code in shorter periods. On the other hand, it allos us to modify the system in small increments, which i’m sure sounds very attractive to all those agile fans out there. It also provides the advantage of partitioning problems into much smaller problems of relatively simple complexity, creating a good problem solving habit. Partitioning a problem makes it easier to identify potential obstacles, and it keeps us from diving into the deep dark waters of confusion when we can’t contain big/complex problems in our heads.

Ok, sold. How do I use it?

We now begin the installation process for PHPUnit.

Note: Use the fullpath /Applications/MAMP/bin/php5/bin/

$ sudo /Applications/MAMP/bin/php5/bin/pear channel-discover pear.phpunit.de
$ sudo /Applications/MAMP/bin/php5/bin/pear channel-discover components.ez.no
$ sudo /Applications/MAMP/bin/php5/bin/pear channel-discover pear.symfony-project.com
$ sudo /Applications/MAMP/bin/php5/bin/pear install phpunit/PHPUnit

If everything goes as planned, we can check the installation by doing:

$ /Applications/MAMP/bin/php5/bin/phpunit --version

We expect:

PHPUnit 3.5.5 by Sebastian Bergmann.

Now we can execute tests using:

$ /Applications/MAMP/bin/php5/bin/phpunit my_tests.php

How to write a test in PHP

We are going to use a coding kata as an example: A string calculator

Tasks:

  1. Read the problem. Here’s a requirements example.
  2. Write a test for one of the requirements. Here’s an example of what a test looks like
  3. Run the test, we expect it to fail. i.e., we get a RED
  4. Implement the solution
  5. Run the test, we expect it to pass. i.e., we get a GREEN
  6. Refactor your solution (Read Uncle Bob’s CleanCode)
  7. Run the test, we expect it to keep working so it should pass again. i.e., we get a GREEN
  8. Go back to step 2 and get the next requirement.

Simplified example (self-explanatory)

index.php

<?php require_once('functions.php'); ?>
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html xml:lang="en" lang="en" xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<title>Born To Code</title>
	</head>
	<body>
		<p><?php echo welcome_message(); ?></p>
	</body>
</html>

functions.php

<?php

function welcome_message() {
	return "Welcome to BornToCode.com";
}
?>

And another functions.php file that will have our test:

<?php
require_once('functions.php');

class FunctionsTest extends PHPUnit_Framework_TestCase
{
    public function testWelcomeMessage()
    {
        $this->assertEquals("Welcome to BornToCode.com", welcome_message());
    }
}
?>

Alright, it’s time to write some code!. If you have any questions, please post it as a comment to this article so we can all learn.

Our next post will talk about Phing, a build framework similar to ANT).


 

Complete PHP Development Environment on OSX – Introduction

On March 1, 2011, in Tutorials, by Born To Code Admins

Our first post will be about a step-by-step tutorial to install and configure all the software needed to develop software in PHP on a Mac in a professional manner.

Why Mac?

Because it’s the most successful Unix-like desktop that doesn’t require a lot of maintenance/configuration, because its hardware is of very good quality, and because I need to have comfortable and reliable tools to perform my work.

Why PHP?

Because it’s an environment suitable for solving a vast range of problems. It performs its tasks very well, and its capabilities make it a very versatile language.

We are also motivated to use PHP because, unfortunately, the PHP community is plagued with workers of a questionable quality. We believe that we can bring some fresh air to the community and offer some good posts.

Development Environment

In order to develop software professionally using PHP, we believe that at least the following components need to be available:

  • PHP 5.x (language interpreter)
  • Apache HTTP Server (web server)
  • PEAR (PHP extensions and components repository)
  • PHPUnit (Unit Testing framework)
  • Phing (Project build system, similar to ANT)
  • Subversion (Revision control system). In the future we might add GIT or Mercurial…
  • Hudson now called Jenkins (Continuous Integration Server)

In this series of articles we’ll explain how to install and configure the components mentioned above, and we’ll explain some possible alternatives and why we believe they could be useful.

PHP and Apache HTTP Server

Even though Mac OS X has Apache and PHP5, we decided that it’d be better to set up isolated copies of Apache and PHP. This would allow us to modify these components and even maintain (with a little bit of effort) several working copies of them.

Having an isolated deployment, in terms of installed versions and the configuration used, is crucial for having a controlled environment in which the production environment can be replicated as closely as possible.

Okay so let’s start by downloading and installing MAMP. Double click on the .dmg, and drag it to your Applications folder. Do this when done:

$ ln -s /Applications/MAMP/bin/php5.3 /Applications/MAMP/bin/php5

Now we need to add the PHP executable path to avoid using the one that comes with OS X:

export PATH=/Applications/MAMP/bin/php5/bin:$PATH

Run it, and also edit your ~/.profile file and put that in there.

Next there’s a small change in the PHP configuration file. We do this by modifying the php.ini file in /Applications/MAMP/conf/php5.3/php.ini and changing:

short_open_tag = On

to

short_open_tag = Off

Since we are modifying the php.ini file, we’ll just take the opportunity to enable XDebug (it’ll be useful later on for the code coverage reports).

The last step before starting with the other packages is to update PEAR. To do this, we run the following:

$ sudo /Applications/MAMP/bin/php5/bin/pear channel-update pear.php.net
$ sudo /Applications/MAMP/bin/php5/bin/pear upgrade pear

…and then we check that everything went according to plan by running

$ /Applications/MAMP/bin/php5/bin/pear -V

and verifying that the output is:

PEAR Version: 1.9.1
PHP Version: 5.3.2

Did it work? Ok, on our next articles we’ll focus on one package at a time, taking the opportunity to talk a little bit about the reason we it should be adopted in our programming practice. A little theory of methodology never killed anybody after all :)

We are ready to start creating our development environment. Stay tuned for the next article, where we’ll talk about PHPUnit, the Unit Testing Framework that we’ll use as an excuse to go over the advantages of Test Driven Development (TDD).


 

Welcome

On January 21, 2011, in General, by Born To Code Admins

Welcome to our blog!

There are several motives that moved us to create this blog, and it was about time that the countless conversations we have about the topics we’ll discuss on this blog were shared with the whole community. We believe that the final push came when we were at Stuttgart, Germany, where Simply Red and a software company  united to screw us over.

Stuttgart, a siberian cold front is punishing europe, it’s extremely cold. We”ve just arrived from Florence, Italy, it’s almost midnight and finding available  rooms has turned into a mission. The city is packed with weekend tourism that arrived to the city for a Simply Red concert. After hours of searching and feeling a bit frustrated because we can’t find a hotel with available rooms, we suddenly see another hotel: it’s on the other side of the road and U-turns are not allowed, so we venture into an industrial neighborhood and we get pulled over by the police, ugh. After wasting our precious time with their routinary stop, we get to the hotel:

-Good evening, have you got any available rooms?

-Yes, I have two…

-(about to shed tears of joy) GREAT!

-…but I can’t give them to you because I don’t know which ones they are.

-what?

-Yeah, our system is down and I can’t see which ones they are.

-WHAT?

-We’ve called the company that provides us with the system, and they say that it’s an outage, but they don’t know how long it’ll take to come back up online.

-WHAT?!?!?!

-I can help you guys out by calling other hotels to see if there are any available rooms so you don’t have to keep driving around…

Well, this good guy called all hotels in the city only to find out that they were all full, at least that saved us some time. At this point, we have very few options: drive to the next city arriving around 3am and try to get a hotel there, or sleep in the car. Sleeping in the car is an awful option, but driving on the autobahn during a snow storm without winter tires and sleepy as hell doesn’t sound very glamorous either, or safe for that matter. We then drove to a gas station and we tried to sleep there…of course that in little less than an hour our bodies woke us up shaking uncontrollably, bordering hypothermia. We woke up and started talking about how bad software quality leads to system outages, and we thought that by writing about high quality design and development was our mission.

Information systems have a great impact that goes well beyond their limit and scope, they are part of our lives. It’s imperative that as professionals, we take each and every development project with a great deal of responsibility and with a high awareness of quality. Information systems can produce transformations: they make business send potential guests to their competition, that two young guys end up without shelter during a snow storm, and that people that didn’t use to write blogs now start doing so.


 

Switch to our mobile site