We are always looking for people wanting to improve Pinax itself. This document outlines the necessary bits to begin contributing to Pinax.
The Pinax source code is hosted on GitHub. This means you must have git installed locally. We recommend you create an account on GitHub allowing you to watch and fork the Pinax source code.
You will want to be sure that your git configuration is set for making commits to a repository. Check the following:
git config user.name
git config user.email
If the output of any of the two commands above are not entirely correct you can easily correct them:
git config --global user.name "First Last"
git config --global user.email "email@somewhere.com"
It is critical you set this information up correctly. It helps us identify who you are when you start giving us those awesome patches.
Once you have forked the Pinax source code you can now make a clone of it to your local disk. To do this:
git clone git@github.com:<username>/pinax.git
This will create new directory named pinax which now contains the Pinax source tree ready for you to get started.
Now that you’ve cloned the source code you are ready to get your environment setup to work on Pinax. This section also applies if you are looking to just run off the latest code. We’ll assume that your current working directory is from within the clone (the pinax directory):
python scripts/pinax-boot.py --development --source=. ../pinax-dev
source ../pinax-dev/bin/activate
If you use virtualenvwrapper you could alternatively do:
python scripts/pinax-boot.py --development --source=. $WORKON_HOME/pinax-dev
workon pinax-dev
Finally, you need to install the dependencies for the development version:
pip install --no-deps --requirement requirements/external_apps.txt
The development version of Pinax is always being updated. You’ll want to make sure you keep up. Your clone of Pinax can easily stay in-sync using git. You will need to setup a git remote to pull in changes from upstream Pinax:
git remote add upstream git://github.com/pinax/pinax.git
Now you will be able to merge in changes that are made upstream:
git fetch upstream
git merge upstream/master
The above will pull in all changes upstream and merge them with your current branch. This can be simplified:
git pull upstream master
To keep your virtual environment in-sync you will need to use pip (make sure you are inside your virtual environment):
pip install --no-deps --requirement requirements/external_apps.txt
Before you begin committing code you’ll want to make sure the Pinax test suite passes. Running the test suite is simple. At the root of your Pinax clone run:
python tests/runner.py
You must be inside the development virtual environment for this to work. If you only want to run a subset of tests (all tests are inside apps) you can specify them explicitly:
python tests/runner.py tasks projects
This useful while developing. However, be sure to run the full suite before committing any code to ensure it doesn’t break other parts of Pinax.
Note
The test runner is new as of November 29, 2009. There are currently many failing tests. We are working on it. This message will be removed when the test suite is generally usable for contributors.
The great thing about using a distributed versioning control system like git is that everyone becomes a committer. When other people write good patches it makes it very easy to include their fixes/features and give them proper credit for the work.
We recommend that you do all your work on Pinax in a separate branch. When you are ready to work on a bug or a new feature create yourself a new branch. The reason why this is important is you can commit as often you like. When you are ready you can merge in the change. Let’s take a look at a common workflow:
git checkout -b task-566
... fix and git commit often ...
git push origin task-566
The reason we have created two new branches is to stay off of master. Keeping master clean of only upstream changes makes yours and ours lives easier. You can then send us a pull request for the fix/feature. Then we can easily review it and merge it when ready.
Writing a good commit message makes it simple for us to identify what your commit does from a high-level. We are not too picky, but there are some basic guidelines we’d like to ask you to follow.
Fixed #1 — added some feature
We ask that you indicate which task you have fixed (if the commit fixes it) or if you are working something complex you may want or be asked to only commits parts:
Refs #1 — added part one of feature X
As said earlier we are not too picky (some core developers may change commit messages before pulling in your changes), but as you get the basics down you make the process of getting your patch into core faster.
Another critical part is that you keep the first line as short and sweet as possible. This line is important because when git shows commits and it has limited space or a different formatting option is used the first line becomes all someone might see. If you need to explain why you made this change or explain something in detail use this format:
Fixed #13 — added time travel
You need to be driving 88 miles per hour to generate 1.21 gigawatts of
power to properly use this feature.
When writing code to be included in Pinax keep our style in mind:
- Follow PEP8 — there are some cases where we do not follow PEP8. It is an excellent starting point.
- Follow Django’s coding style — we’re pretty much in agreement on Django style outlined there.
We would like to enforce a few more strict guides not outlined by PEP8 or Django’s coding style:
- PEP8 tries to keep line length at 80 characters. We follow it when we can, but not when it makes a line harder to read. It is okay to go a little bit over 80 characters if not breaking the line improves readability.
- Use double quotes not single quotes. Single quotes are allowed in cases where a double quote is needed in the string. This makes the code read cleaner in those cases.
- Blank lines are indented to the appropriate level for the block they are in.
- Docstrings always use three double quotes on a line of their own, so, for example, a single line docstring should take up three lines not one.
- Imports are grouped specifically and ordered alphabetically. This is shown in the example below.
- Always use reverse and never @models.permalink.
- Tuples should be reserved for positional data structures and not used where a list is more appropriate.
Here is an example of these rules applied:
# first set of imports are stdlib imports
# non-from imports go first then from style import in their own group
import csv
from datetime import datetime
# second set of imports are Django imports with contrib in their own
# group.
from django.core.urlresolvers import reverse
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
# third set of imports are Pinax imports
from pinax.utils.examplelib import function_name
# forth set of imports are external apps (if applicable)
from tagging.fields import TagField
# fifth set of imports are local apps
from pinax.apps.tasks.fields import MarkupField
class Task(models.Model):
"""
A model for storing a task.
"""
creator = models.ForeignKey(User)
created = models.DateTimeField(default=datetime.now)
modified = models.DateTimeField(default=datetime.now)
objects = models.Manager()
class Meta:
verbose_name = _("task")
verbose_name_plural = _("tasks")
def __unicode__(self):
return self.summary
def save(self, **kwargs):
self.modified = datetime.now()
super(Task, self).save(**kwargs)
def get_absolute_url(self):
return reverse("task_detail", kwargs={"task_id": self.pk})
# custom methods
class TaskComment(models.Model):
# ... you get the point ...
pass