17
Getting Started with GoogleCode and Mercurial
I put a few of my Python projects on GoogleCode last week and learned quite a few things that I thought I would share.
Setting It Up
If you want to start a GoogleCode project you’ll need the project creation page. Enter a project name (all lower case), summary, and description. For version control, select Mercurial, and go with whichever license suits you best. Add a few labels and create your project. You should then be taken to your project page, which you’ll probably want to bookmark.
The second piece you’ll need (if you don’t have it already) is Mercurial for your source code version control. Before I had projects on GoogleCode, I use Mercurial in single-player fashion, saving revisions of my own projects so I didn’t have to worry about making major or possibly risky changes.
Mercurial
Presuming you are putting an existing project on GoogleCode, the first thing you’ll want to do is have a repository to push to the servers. Using the command line (or Dos prompt if you’re using Windows), navigate to the folder containing your code. You’ll need to create a repository, add your code to it, and commit it. You can use the following commands:
hg init hg add hg commit -m "Initial commit."
There are options for the add command, such as hg add -X [pattern]. This excludes files matching a certain pattern. I typically don’t include .pyc files in my repositories, so often I’ll use hg add -X *.pyc
If you haven’t used Mercurial before, you’ll need to set up an hgrc file somewhere. There are several places you can put the file (see the link), and you can even have multiple files that Mercurial will combine (more on this later). For now, create a new file in your home directory called “.hgrc” (again, see the link above for details). Put the following information in the file:
[ui] username = Your Name <youremail@server.com> verbose = True
This tells Mercurial who made a commit (useful when looking through your revision log) and instructs Mercurial to show more output when doing things rather than less.
When working with GoogleCode, user authentication is required to push changes. You’ll need your Google username and the code/password generated by GoogleCode (go to the Sources tab and click the link for “googlecode.com password”). If you don’t do the following steps to do authentication automatically, you’ll have to enter your username and password each time you push, which, given the kind of generated password GoogleCode produces, is a pain.
To authenticate automatically, add an authorization section to your hgrc file.
[auth] project.prefix = https://projectname.googlecode.com/hg/ project.username = your.username project.password = geNeRAteDpasSWOrd
You can put multiple prefixes, usernames, and passwords here, using something else instead of “project.”. One irritating thing is that you have to repeat your name and password for each project, even if they’re the same. It would be nice if there was a way to reference a variable containing the data, but if there is, I haven’t found it. If anyone knows how, let me know (but it’s not a big deal).
If you decide to do this, it’s important to make sure your hgrc file is not publicly visible, as in, stored in your repository somewhere. You can put an hgrc file in the .hg directory in your repository, and putting your password in there isn’t a good idea.
Speaking of the hgrc file in your repository, let’s make one. Create a file named “hgrc” in the .hg folder in the folder containing your code. This step is another convenience step, meant to make pushing your code easier. Generally, without this step, you’ll have to issue the command hg push https://yourproject.googlecode.com/hg/ Adding this section to the repository’s hgrc file allows us to use simply hg push
[paths] default-push = https://yourproject.googlecode.com
You should now be able to push your code to the GoogleCode servers. One thing I learned when I first did this is that your entire version history will go on GoogleCode, not simply your latest revision. In retrospect, this makes perfect sense since version control is simply a history of changes, all of which you’ll need to create the most recent version.
Added Bonus: Externals and Subrepos
One of the issues I discovered with serving code from a repository is how to manage external dependencies. I have several modules I use on a regular basis, for instance, a module of commonly used decorators. None of this modules, however, warrants a project that I could upload and list as a dependency for all my other projects, and of course, you don’t want to simply copy the module and add it to each repository that uses it (maintaining the same code in different places is not only a pain, but a bad design idea in general).
Enter the helpful folks at subrepositories, an experimental feature in Mercurial version 1.3 and up. I’ve used it a little, and I’m still seeing how well it works, but on first glance, it seems to be the right idea. Here’s how I resolved my problem.
Put your external dependencies in a folder and make it a repository with the simple sequence hg init; hg add; hg commit -m "Log" You don’t need to worry about the hgrc file this time, since, if you put your username in the home directory, Mercurial will look there for it.
Now, navigate back to your main project’s folder. I keep my projects in a Code folder, among them a folder named “externals” with the code I often reuse between different projects. If you have a different scheme, you’ll have to adjust the following instructions accordingly.
You’ll have to do four things: create the .hgsub file, clone the externals repository, add the subrepository to the project, and commit. First, create the “.hgsub” file in the main project directory. Put in it the line externals = ../externals This tells Mercurial where to check for updates. For the other three steps, execute the following commands:
hg clone ../externals externals hg add hg commit -m "Added externals subrepository."
When you issue the “add” command, you might not see anything happen. That’s okay. I know I started trying to troubleshoot when I didn’t see anything happen, but it does the work on the commit, so you don’t have to worry. (Mercurial will also create a .hgsubstate file that it needs but you don’t need to worry about.)
The last thing to do is push your updated repository. Mercurial will pull changes for the subrepository from the repository listed in the .hgsub file. (I’m not sure if it does this on commit or push.) You can include multiple subrepositories by repeating the process.
Conclusion
That’s my experience putting projects on GoogleCode. Let us know yours in the comments.
21
Week In Links – 8/21/2009
Over the last few weeks I’ve noticed a few things,
- I always have a lot of links open in FireFox that I haven’t looked at yet.
- Blog traffic drops like mad on Fridays
These are just some sites or articles that I found interesting or helped me in some way this week.
So here’s what I have this week! (other posters can add to this page as they wish)
- http://www.infoq.com/articles/agile-version-control
- http://kenai.com
- http://oauth.net
- http://code.google.com/p/modwsgi/wiki/DebuggingTechniques
- http://blog.lowkster.com/2008/01/getting-to-pesky-foreign-key-data-in.html
- http://www.box.net
- http://beanstalkapp.com
- http://www.ducea.com/2006/08/11/apache-tips-tricks-deny-access-to-some-folders
- http://www.fogcreek.com/FogBugz
- http://www.sitepoint.com/article/build-to-do-list-30-minutes
5
PHP5-CLI versus Python CLI
I just thought this was kind of interesting. Out of the box CLI comparison of PHP and Python type errors
Python
>>> test = 123
>>> test2 = "ewfwef"
>>> test / test2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for /: 'int' and 'str'
PHP
$test = 123;
$test2 = "werwe";
echo $test/$test2;
Warning: Division by zero in Command line code on line 1
It’s nice that python tells you what is really wrong here, you can’t divide an integer by a string! PHP on the other hand implies that $test2 is equivalent to 0.
It should be noted that python is doing a trace and PHP is not. Doing a trace on the error in PHP would give more information but since PHP is very weak with types, you would probably have to notice the error on your own.
10
# Function/Method Decorators
One of the reasons I like Python is because it’s simple but powerful. All the tools are there for whatever task needs to be done. I’ve found __getattr__ to be a very useful tool for creating sets of standardized class methods without having to explicitly declare them. Another useful tool is function decorators. Read on to get a quick idea of how to make your own class decorators.
2
Making a To Do Timeline with Excel
I used to use Outlook for my task-keeping, or more specifically a PDA syncing with Outlook. Recently I’ve switched to using an iPod Touch, which does not come with anything for making to do lists, let alone something that syncs with Outlook and is as helpful as what Windows Mobile uses.
Necessity, however, is the mother of invention. I’ve adopted to using Excel as my to do list, and I actually like it much better than what I used to use. Read on for details.
18
# Iterators
I got the Gang of Four book on design patterns a couple of years ago and it was way beyond me (Alex Martelli at Google doesn’t suggest it as an introduction, I’ve since learned). I still haven’t mastered it, but every now and then I do find a useful idea.
Let me introduce you to the object-oriented idea of iterators.
10
Python Scripting within a Python Script
UPDATE: In order to use reload in Python 3, it must be imported from the imp built-in module. Thus, some of the examples below will require the line from imp import reload in order to work in Python 3.
I’ve been mulling over an idea for a little while now, but didn’t have the chance to do anything with it until today. Turns it it was way easier than I thought it would be. For reasons I won’t go into here, I wanted to have a Python program which could write and run other Python programs. Clearly Python can write programs (since it can save text as a .py file), and it can easily run programs just by importing a module. The trouble was editing those files and running the updated code in the master program without having to restart the master program. Here’s how I did it.

