I recently began working on a project based on Pinax. The Pinax project's goal is to develop a set of re-usable applications for the Django Web Framework that are common in website development. Generally, these applications provide the functions and features common in social media sites. For reference, Bob Haugen has also posted how to do this on a wiki page in the Pinax tribe on Cloud27.

For the purposes of this example, I've set up a temporary space called Slaptijack for my Subversion repository at Assembla.

  1. The first thing to do is create our main repository directory structure. In other words, let's create the branches, tags, and trunk directory and import this into our new repository.
    $ mkdir Slaptijack-tmp
    $ cd Slaptijack-tmp
    $ mkdir trunk tags branches
    $ svn import --message "Initial directory import." http://svn.assembla.com/svn/cmlzpiJn0r3Azzab7jnrAJ
    Adding         trunk
    Adding         branches
    Adding         tags
    
    Committed revision 1.
  2. Now you can remove that temporary directory we created for the Subversion import.
    $ cd ..
    $ rm -r Slaptijack-tmp
  3. It's time to checkout our new project. Notice that I'm checking out the trunk here instead of the whole repository.
    $ svn checkout http://svn.assembla.com/svn/cmlzpiJn0r3Azzab7jnrAJ/trunk Slaptijack
    Checked out revision 1.
  4. We need to enter our project directory and export the Pinax project directory. We want to export the Pinax project into our own project name. It's important to do an export here, because we're going to add this directory into our Subversion repository. Obviously, we don't want a bunch of .svn cluttering up our import.
    $ cd Slaptijack
    $ svn export http://django-hotclub.googlecode.com/svn/trunk/pinax slaptijack
    A    slaptijack
    A    slaptijack/manage.py
    <snip>
    A    slaptijack/templates/about/about.html
    A    slaptijack/templates/about/terms.html
    Exported revision 962.
  5. Change into the project directory (slaptijack in my case) and clean up any references to pinax in settings.py. This seems like a good time to mention that you can create a file called localsettings.py for settings that should only be used in your development environment or otherwise override the main settings file.
  6. Once you've made the necessary changes, ascend one directory and add your new directory into the repository.
    $ cd ..
    Baldr:Slaptijack scott$ ls
    slaptijack
    $ svn add slaptijack
    A         slaptijack
    A         slaptijack/__init__.py
    <snip>
    A         slaptijack/utils
    A         slaptijack/utils/gradient.py
    $ svn --message "New pinax project dir" commit
    Sending        .
    <snip>
    Transmitting file data .....................................................
    Committed revision 2.
  7. Now we've got the main project directory set up, it's time to add the real meat of the pinax project. We'll do that via the svn:externals Subversion repository. This way we'll always have the latest and greatest version of each re-usable application. You might find in your environment that it makes sense to tie each external to a particular revision. If that's the case, go for it!

    Instead of using individual propset commands, I'm going to use the propedit command to add all the externals at the same time. For this to work, you will probably need to have the EDITOR environment variable set. In my case, that's vim. Change into your top-level project directory and start from there.

    $ svn propedit svn:externals .
    # The following is the contents of the vim file. Saving 
    # the changes and exiting vim executes the svn command.
    core_apps     http://django-hotclub.googlecode.com/svn/trunk/core_apps
    external_apps http://django-hotclub.googlecode.com/svn/trunk/external_apps
    external_libs http://django-hotclub.googlecode.com/svn/trunk/external_libs
    local_apps    http://django-hotclub.googlecode.com/svn/trunk/local_apps
    Set new value for property 'svn:externals' on '.'
    $ svn --message "Bringing in externals" commit
    Sending        .
    
    Committed revision 3.
  8. To get our externals brought into our work space, we'll need to issue an update. There are a lot of external applications, so be patient.
    $ svn update
    
    Fetching external item into 'core_apps'
    A    core_apps/about
    A    core_apps/about/views.py
    <snip>
    A    local_apps/things_app/templatetags/extra_voting_tags.py
    A    local_apps/things_app/models.py
    Updated external to revision 965.
    
    Updated to revision 3.
    $ ls
    core_apps
    external_apps
    external_lib
    local_apps
    slaptijack
  9. At this point, you should have a working Pinax-based project in your Subversion repository. The only thing you might consider is having Subversion ignore *.pyc and SQLite3 database files. Here's how I did it.
    1. First, create a temporary text file with the following two lines. I called mine /tmp/slaptijack.
      *.pyc
      *.db
    2. Next I ran the following command at the top level of my repository trunk to apply the ignore settings to all directories:
      $ find . -type d -name .svn -prune -o -type d -exec svn propset svn:ignore -F /tmp/slaptijack {} \;
    3. Finally, let's have our project directory ignore the localsettings.py file. We don't want to accidentally upload some configuration that will break our production environment.
      $ svn propset svn:ignore localsettings.py slaptijack

    Like Bob Haugen, I had a similar problem where Subversion wanted me to update before I could commit. This is possibly related to the external directories.

I think that just about wraps up everything I did. If I missed a step or didn't adequately explain something, please leave a comment or let me know.