GettingStartedIRCSession

Not logged in - Log In / Register

Revision 1 as of 2009-09-03 19:24:45

Clear message

IRC session: "Getting started with Launchpad development"

Graham Binns conducted an IRC session entitled Getting started with Launchpad development on of 2 September 2009, as part of Ubuntu Dev Week. Here's a transcript:

<gmb> My name's Graham Binns. I'm a member of the Launchpad Bugs
      development team.

<gmb> I'm going to talk today about getting started with Launchpad
      development, in the hope that it might make it easier for you guys
      to contribute patches to scratch your least favourite itches.

<gmb> Hopefully you'll have all completed the instructions at
      http://dev.launchpad.net/Getting so that you can follow along with
      this session. If not, you might struggle a bit, but you can always
      go back once the session is over and follow it through on your own
      time.

<gmb> If you've any questions, please shout them out in
      #ubuntu-classroom-chat and prefix them with QUESTION so that I can
      see them easier :)

<gmb> Okay, so, first things first, we need to find us a bug to fix. For
      the purposes of this session I've filed a made-up bug on staging
      for us to fix https://staging.launchpad.net/bugs/422299. I've gone
      with this because:

<gmb> 1) It's fairly simple to fix. 2) It's easy to demonstrate our
      test-driven development process whilst we fix it, which is why I
      didn't pick a bug in the UI. 3) There were no really trivial bugs
      available for us to try this out on :).

<gmb> When you're working on fixing a bug in Launchpad, you nearly
      always want to be doing it in a new branch.

<gmb> We try to keep to one bug per branch, because that means that it's
      much easier to review the patches when they're done (because
      they're smaller, natch :))

<gmb> So, let's create a branch in which to fix the bug.

<gmb> If you've set up the Launchpad development environment properly
      according to http://dev.launchpad.net/Getting, you should be able
      to run the following command:

<gmb> $ rocketfuel-branch getting-started-with-lp-bug-422299

<gmb> Note that I've appended the bug number to the branch

<gmb> so that I can always refer to it if I need to

<gmb> but I've also given the branch a useful name to help me remember
      what it's for if I have to leave it for a while.

<gmb> rocketfuel-branch takes a few seconds, so I'll just wait a minute
      for everyone to catch up.

<gmb> (By the way, if anyone has any problems with rocketfuel-get or any
      other part of this lesson, please come find me afterwards in
      #launchpad and I'll try to help you out)

<gmb> s/-get/-branch/ there, sorry.

<gmb> Okay.

<gmb> Now, at this point, once you'd decided how to fix the bug

<gmb> but - importantly - before you start coding

<gmb> you'd ideally have a chat with a member of the Launchpad
      development team about your intended fix.

<gmb> We normally do this either on IRC or on Skype, depending on your
      preference.

<gmb> You can usually find a Launchpad developer in #launchpad-dev on
      Freenode who'll be available for one of these calls.

<gmb> The call gives you a chance to ensure that what you're doing is
      actually sane.

<gmb> For some bugs there's only one possible fix, complex or
      otherwise. For others there may be many ways to do it, and it's
      important to pick the right one.

<gmb> If your solution is particularly complex or you need to
      demonstrate *why* you want to do things the way you do, it may
      help to write some tests to reproduce the bug before you have the
      call.

<gmb> Note that the tests should always fail at this point;

<gmb> you shouldn't make any changes to the actual code until you've had
      the pre-implementation call or chat with an LP developer.

<gmb> Okay, so that's the info-dumpy bit of this session over for now :)

<gmb> Sorry about that, all.

<gmb> I have a rather flaky connection today :)

<gmb> As I was saying...

<gmb> Under lib/lp you'll find most of the Launchpad code, split up into
      its applications.

<gmb> So, `ls lib/lp` in your new getting-started-with-lp-bug-422299
      branch should give you something like this:

<gmb> $ ls lib/lp

<gmb> answers           archiveuploader  buildmaster  coop
      registry  soyuz

<gmb> app               blueprints       code         __init__.py
      scripts   testing

<gmb> archivepublisher  bugs             codehosting  __init__.pyc
      services  translations

<gmb> Now, we know that we're working in the bugs application, so lets
      take a look in there to see where to put our tests:

<gmb> $ ls lib/lp/bugs

<gmb> adapters        emailtemplates      help          model
      stories      windmill

<gmb> browser         event               __init__.py   notifications
      subscribers  xmlrpc

<gmb> configure.zcml  externalbugtracker  __init__.pyc  pagetests
      templates

<gmb> doc             feed                interfaces    scripts
      tests

<gmb> There are three types of test in Launchpad: doctests, which live
      in lib/lp/$app/doc; stories, which live in lib/lp/$app/stories and
      unittests, which live in lib/lp/$app/tests.

<gmb> In this case we want to add to an existing doctest, so I'll stick
      with that for now and we can come back to what the others are for
      later.

<gmb> So, in lib/lp/bugs/doc/ you'll find a file called
      externalbugtracker-trac.txt.

<gmb> This is the test we want to modify, so feel free to open it in
      your text editor and take a look at line 110, which is where we're
      going to add our test.

<gmb> For the sake of making this quicker, I've already created a diff
      of the change that I'd make here:
      http://pastebin.ubuntu.com/263869/plain/

<gmb> You can save that to disk somewhere (e.g. /tmp/diff) and then
      apply it as a patch using `bzr patch /tmp/diff` in the root of
      your new Launchpad branch.

<gmb> The test we've just added is really simple.

<gmb> It passes 'frobnob' to the convertRemoteStatus() method of a Trac
      instance (which is just an abstraction that lets us talk to an
      actual Trac server)

<gmb> and expects to get "Fix Released" back.

<gmb> Of course, it doesn't since we haven't implemented that yet :).

<gmb> Once we've written the test, we run it to make sure it fails.

<gmb> This part is very important: your tests should always fail first
      and only after they fail do you write the code to make them pass.

<gmb>  That means that you can use the tests to build a good spec of how
      your module / class / function / whatever should behave.

<gmb> It also means that, like I said before, you can use the failing
      tests to demonstrate what your fix will actually change to whoever
      you have a call with.

<gmb> To run this specific test only, we use the `bin/test` command:

<gmb> $ bin/test -vvt externalbugtracker-trac.txt

<gmb> That might take a short while to run (Launchpad's test suite can
      be frustratingly slow sometimes, but don't let that put you off;
      the payoff is worth it)

<gmb> The output from which should look something like this:
      http://pastebin.ubuntu.com/263874/

<gmb> Note the important bit:

<gmb>     File "lib/lp/bugs/tests/../doc/externalbugtracker-trac.txt",
      line 111, in externalbugtracker-trac.txt

<gmb>     Failed example:

<gmb>         trac.convertRemoteStatus('frobnob').title

<gmb>     Exception raised:

<gmb>         Traceback (most recent call last):

<gmb>           File
      "/home/graham/canonical/lp-sourcedeps/eggs/zope.testing-3.8.1-py2.4.egg/zope/testing/doctest.py",
      line 1361, in __run

<gmb>             compileflags, 1) in test.globs

<gmb>           File "<doctest externalbugtracker-trac.txt[line 111,
      example 35]>", line 1, in ?

<gmb>           File
      "/home/graham/canonical/lp-branches/lesson/lib/lp/bugs/externalbugtracker/trac.py",
      line 265, in convertRemoteStatus

<gmb>             raise UnknownRemoteStatusError(remote_status)

<gmb>         UnknownRemoteStatusError: frobnob

<gmb> This tells us that the test failed, which is exactly what we
      wanted.

<gmb> (Yes, copying and pasting in IRC makes me a bad man.)

<gmb> nvertRemoteStatus() raised an UnknownRemoteStatusError instead of
      giving us back the status we wanted.

<gmb> Which was, of course, the 'Fix Released' status.

<gmb> At this point, you might want to commit the changes:

<gmb> $ bzr commit -m "Added tests for bug 422299."

<gmb> Again - I can't emphasise this enough - the fact that your test
      fails is a Good Thing. If it didn't fail, it wouldn't be a good
      test, since we know that the bug actually exists in the code.

<gmb> Now that we have a test that fails, we want to add some code to
      make it pass

<gmb> We want to add this to lib/lp/bugs/externalbugtracker/trac.py.

<gmb> Now, as it happens, I knew that before I started, but you can work
      it out by looking at the top of the doctest file that we just
      edited.

<gmb> So, open lib/lp/bugs/externalbugtracker/trac.py now and take a
      look at line 258. We'll add our fix here.

<gmb> The fix is really simple, and we can pretty much copy line 255 and
      alter it to suit our needs.

<gmb> We want 'frobnob' to map to 'Fix Released', so we add the
      following line:

<gmb>     ('frobnob', BugTaskStatus.FIXRELEASED),

<gmb> I'll not go into the nitty-gritty of how status lookups work here,
      because it's unimportant.

<gmb> Suffice it to say that in Trac's case it's a simple pair of
      values, (remote_status, launchpad_status).

<gmb> Here's a diff of that change: http://pastebin.ubuntu.com/263882/

<gmb> Now that we've added a fix for the bug, we run the test again:

<gmb> $ bin/test -vvt externalbugtracker-trac.txt

<gmb> This time, it should pass without any problems...

<gmb> and it does

<gmb> http://pastebin.ubuntu.com/263885/

<gmb> So, now we commit our changes:

<gmb> $ bzr ci -m "Fixed bug 422299"

<gmb> (Note that this is a lame description of the fix; you should use
      something more descriptive).

<gmb> So, we now have a branch that fixes a bug. Hurrah and all that.

<gmb> Now we need to get it into the Launchpad tree.

<gmb> Launchpad developers use the Launchpad code review system to
      review Launchpad branches.

<gmb> You can't land a branch without having it reviewed first

<gmb> This allows us to ensure that code quality stays high

<gmb> And it also acts as a  sanity check to make sure that the
      developer hasn't done something unnecessarily odd in their fix.

<gmb> So at this point, you need to push your branch to Launchpad using
      the `bzr push` command:

<gmb> $ bzr push

<gmb> Once the branch has been pushed up to Launchpad it gets its own
      page in the Launchpad web interface, which you can look at by
      running:

<gmb> $ bzr lp-open

<gmb> This should open the page in your default browser.

<gmb> Now that you've fixed the bug and pushed the branch to Launchpad
      you need to request a review for it.

<gmb> To do this, go to the branch page in your browser and click the
      "Propose for merging into another branch" link.

<gmb> This will take you to a page that looks like this:

<gmb> http://people.ubuntu.com/~gbinns/propose-merge.png

<gmb> In the "Initial comment" box, you need to type a description of
      the branch.

<gmb> For example, for this branch I'd write something like:

<gmb> "This branch fixes bug 422299 by making Trac.convertRemoteStatus()
      map the "frobnob" status to Launchpad's Fix Released status."

<gmb> After you've typed in your description, hit the "Propose merge"
      button and you should see a page that looks something like this:
      https://code.edge.launchpad.net/~gmb/launchpad/lesson/+merge/11068

<gmb> You then need to head on over to #launchpad-reviews on Freenode
      and ask if anyone's available to review your branch.

<gmb> If there's no-one available at the time, don't worry.

<gmb> We have a reviewer schedule:
      http://dev.launchpad.net/ReviewerSchedule, so someone should take
      a look at it withing 24 hours.

<gmb> The reviewer may ask you to make changes to your branch

<gmb> To bring your fix into line with our coding standards

<gmb> Or maybe to fix a bug that they've spotted in your fix.

<gmb> Once the reviewer has signed off on the changes, they'll submit
      the branch for merging for you.

<gmb> When a branch gets merged, the entire test suite is run against it

<gmb> If any of the tests fail

<gmb> The reviewer may ask you to help fix them

<gmb> But it's likely that someone else will take care of it if you're
      not around at the time

<gmb> And that's about all there is to simple Launchpad development :)

<gmb> Are there any questions? Please shout them out in
      #ubuntu-classroom-chat

<gmb> < ahe> QUESTION: When will launchpad be available as a package in
      the standard distribution?

<gmb> ahe: At this point, there aren't any plans for that. We released
      the code for Launchpad because we wanted to let people help to
      improve the service, but we've no plans as far as I'm aware to
      distribute it as a package.

<gmb> < Andphe> question: have you planned guys, offer launchpad in
      another languages than english, example spanish ?

<gmb> Andphe: It's something that we've considered and that we would
      like to do at some point, at least for certain parts of the
      interface.

<gmb> The problem is that launchpad is meant to be a global
      collaboration tool, and if we translate it wholesale into other
      languages that automatically means that a certain amount of
      collaboration will be lost

<gmb> For exampel, if a user reads the interface in Spanish and files a
      bug in Spanish, how am I, an non-Spanish speaker, going to be able
      to deal with that bug report?

<gmb> However, internationalisation would work quite well for the
      Answers application, and it's already built with that in mind.

<gmb> < ahe> QUESTION: Do you deploy launchpad manually or are there
      some helper scripts or stuff like that to ease the deployment in a
      production environment?

<gmb> It's a combination of the two.

<gmb> edge.launchpad.net is deployed by a script every night, as is
      staging.launchpad.net.

<gmb> The production servers are updated manually by our sysadmins at
      least once per cycle (though it's usually more than that since we
      discover urgent bugs that need to be fixed).

<gmb> < Andphe> question: if answers already support another languages,
      how can we help to translate it ?

<gmb> Andphe: It's built with translation in mind, but I don't know what
      work needs doing to make it translatable.

<gmb> Andphe: Your best bet would be to join the Launchpad Developers
      mailing list (http://launchpad.net/~launchpad-dev) and post a
      question about it there.

<gmb> I think that's about all we've got time for.

<gmb> If you've any further questions, please feel free to join the
      Launchpad Dev list (above)

<gmb> And ask there.

<gmb> Everyone's welcome to contribute.

<gmb> Thanks very much for your time.