views:

269

answers:

6

Subversion is a great way to update our web applications on our servers. With a simple svn update all changed files get... well, changed.

Except for the omnipresent configuration files such as config.php which hold the database access configuration, server paths etc. And are therefore different on my local development system and the remote server.

With the update command, a file modified on the server won't get overwritten, but if I change the file locally and commit it, the server gets the wrong configuration file.

But I don't want to set the svn:ignore property either, since the config file belongs to the project.

Is there a Subversion-mechanism which will allow me to easily handle these kind of files? Or is the only way to solve this problem to make a system switch within the config file which will determine the executing system and sets the configuration accordingly?

+3  A: 

Create a template for the file (e.g. config.php-default) and let the user copy the template. She can also do a diff to see what changed between versions to incorporate these changes in the locally deployed version of the file.

xmjx
That's a good idea too, I like it for its simplicity.
christian studer
+1  A: 

On the projects I am currently working on we have 2 properties files for the database schema information - one for the production environment and one for development. We have a class that loads all of our properties for the module being executed, with logic that determines which file to load.

Since our development environment locally is a Windows file system and the production servers operate on UNIX file systems, our solution was to determine the operating system of the host and load the correct file.

We keep these directly within our source control in order to keep a history of any changes made. I think we learned a lesson from our (internal) client finger pointing in regards to INSANELY FREQUENT REQUIREMENTS CHANGES, in that we needed to be able to defend any of the past changes to the files.

This may be unique for our situation, but I've found this to be extremely helpful, especially if I am trying to replicate a test run from a previous revision.

KG
+1  A: 

Some possible solutions:

If you are using a J2EE app server, you can look up properties through JNDI, there are tools to easily set and view them on the server.

You can have a default properties file in your subversion server, but look elsewhere on the servers (outside the parts of the project that are checked into svn) for the real properties file, but then you usually get OS dependent paths and have to remember to update the real properties files manually when you add new properties in your svn file.

You can set the properties in a properties file as part of the build, and pass in a parameter to the build command to tell it which server environment to build for. This can feel a bit roundabout, and you have to remember to update the build script with new properties. But it can work well - if you set up a Continuous Integration server, it can build for all the different environments and test the bundles for you. Then you know you have something deployment ready.

Lars Westergren
I'm not on an J2EE server, but the general principle remains the same: Build a switch into the code.
christian studer
+1  A: 

I find the easiest way is to switch on the machine's hostname. I have a .ini file with a general section that also overrides this for production, testing and development systems.

[general]
info=misc
db.password=secret
db.host=localhost

[production : general]
info=only on production system
db.password=secret1

[testing : general]
info=only on test system
db.password=secret2

[dev : general]
info=only on dev system
db.password=secret3

So dev:db.password == 'secret3', but dev:db.host == 'localhost', from the original 'general' group.

The 'production', 'testing' and 'dev' could be the machine hostnames, or they are aliases for them set from some other mechanism in a configuration control script.

Alister Bulman
This seems to be the general idea, thank you.
christian studer
For the record, I use the Zend Framework Zend_Config_Ini to achieve this. The inheritance effect is out-of-the-box functionality for it.
Alister Bulman
I don't think that this scales ... at all.
xmjx
+2  A: 

You may want to consider the fact that developers won't (And probably shouldn't) have access to the username/passwords for the production machine.

To cope with this, such configuration should be considered to be 'deployment details', rather than overall application configuration. Even when you make this conceptual distinction, you still need to deal with the different deployment environments but, as you seem to be dealing with PHP, I can't comment on specifics for your case.

As Lars mentioned, one possible J2EE solution is to store such details under JNDI, making the exact same application binary deployable on any environment, leaving DBAs/Admins to set the username/password for each machine.

belugabob
+1  A: 

You can also make your config file domain depended. This way you can create a configuration for you local machine and for the production server(s). You do need to build the logic of course to handle this.

If you run apache webserver you can easily configure it to have every developer using their own (sub)domain on their local box instead of just using localhost. This way, every developer can use their own configuration.