== Dev Week -- Fixing obvious bugs in Launchpad -- deryck -- Tue, Jul 12th, 2011 == {{{#!irc [19:02] Ok, so I guess that's me. Hi, all. :) [19:02] My name is Deryck Hodge. I'm a team lead for one of the dev teams working on Launchpad. [19:02] This session will be about fixing obvious bugs in Launchpad. [19:02] Feel free to ask questions as we go. [19:02] Launchpad is a large code base with a complex deployment story, so one way into hacking on Launchpad is to start by fixing obvious or easy bugs. [19:02] From there you can decide if you want to go deeper or spend more time working on Launchpad. [19:03] Working on lp is great by itself, but also a great way to support Ubuntu development. [19:03] The goals for this session then are to: [19:03] * show you how to setup a Launchpad dev environment [19:03] * give you a tour of the Launchpad codebase [19:03] * teach you how to find easy bugs [19:03] * demonstrate how to approach fixing a bug [19:04] You can try to follow along if you like, but I'm not assuming that, since certain steps like branching can take time.... [19:04] I'll just outline and demo here. [19:04] So, let's start with getting a Launchpad dev environment setup. [19:05] Launchpad uses a set of scripts we refer to as "rocketfuel" to manage our dev environment. These live in the Launchpad devel tree and all begin with "rocketfuel-" names. [19:05] So rocketfuel-setup would be the script you would run to build a dev environment. [19:05] A word of warning.... [19:06] This script appends to your /etc/hosts file, adds ppa sources for launchpad development, and adds local apache configs. [19:06] If that scares you, don't run the script. If it doesn't, then you can get a working environment by downloading the script and running it, like: [19:06] * bzr --no-plugins cat http://bazaar.launchpad.net/~launchpad-pqm/launchpad/devel/utilities/rocketfuel-setup > rocketfuel-setup [19:06] * ./rocketfuel-setup [19:07] (I'm pasting from notes, so the "*" has no meaning, it's just my bullet points I copied by accident.) [19:08] The above will install into $HOME/launchpad by default. But it does look for some env variables if you want to install in non-standard places. [19:08] I change things myself, so my $HOME/.rocketfule-env.sh looks like: [19:08] http://pastebin.ubuntu.com/642768/ [19:09] If you create this file before running rocketfuel-setup, you'll get things in the places you want them. Or just go with the defaults. :) [19:10] If you want to do each step of rocketfuel-setup by hand rather than run the script, see the full instructions at: [19:10] https://dev.launchpad.net/Getting [19:10] Under the "Do it yourself" section [19:11] If you want to run rocketfuel-setup for convenience but want it isolated a bit, you can run launchpad in a vm, or use an LXC container or a chroot. [19:11] For more on that, see: [19:11] https://dev.launchpad.net/Running/LXC or https://dev.launchpad.net/Running/Schroot [19:12] The point of all of the above is to get you familiar with getting setup and point you to sources of more info. [19:12] You don't have to do this now to continue following along... but feel free, of course. [19:12] Okay, so after you do all that you should be able to browse the local tree. If you're using the default location you can see it at $HOME/launchpad/lp-branches/devel. [19:13] Now, you need a working database setup. [19:13] This is as simple as changing into the lp tree and running: [19:14] ./utilities/launchpad-database-setup $USER && make schema [19:14] where $USER is whatever local user you want to access the db with. [19:14] A warning again..... [19:14] If you already have a working Postgres setup, this will destroy any existing DBs. So run isolated per suggestions above if you need to. [19:15] Also "make schema" is your friend if you get your DB in a weird state. It always resets the DB for development. [19:15] Now we can run the local Launchpad with: make run [19:16] This takes a minute to start up but you should be able to go to https://launchpad.dev/ in your browser and connect. [19:16] You can also run tests here. By killing the running lp and trying something like: [19:16] ./bin/test -cvvt test_bugheat [19:16] Testing becomes important as we do changes later. We'll come back to that. [19:17] Any questions so far on getting setup and running lp locally? [19:18] Now that we're setup (or at least know how to get setup), let's look at the code itself! [19:18] You can ls the top of the tree to see what's there: ls -l ~/launchpad/lp-branches/devel [19:18] But the interesting bits are in lib, especially lib/lp and lib/canonical. [19:19] lib/canonical is a part of the tree that we can't seem to get rid of. Eventually everything should end up moved to lib/lp... [19:19] ...but if you can't find something in lib/lp, then look in lib/canonical. [19:19] Everything under the lib directory are the Python packages we'll deal with. So lib/lp/bugs/model/bug.py can be referenced in Python by lp.bugs.model.bug. [19:20] Here's a paste to make this clear: [19:20] http://pastebin.ubuntu.com/642785/ [19:20] Notice in the paste that there is a bin/py in the tree that allows you to use Python with the correct path set for lp development. [19:21] You can use `make harness` at the top of the lp tree to get a Python shell with several objects available already. [19:21] This is nice for interpretative debugging or figuring things out. [19:22] So to understand the tree structure, let's focus on lib/lp since that's where most everything lives these days. [19:22] Each component of launchpad.net has it's own directory in the lp tree. "bugs" and "code" and "translations" and so on. [19:22] Each of these has roughly the same structure.... an interfaces, model, browser, and templates directory.... among other directories that are common. [19:23] so lp.bugs.model and lp.code.model and so on. [19:23] This is roughly our MVC division in launchpad, for those who know MVC-style development from other web app frameworks like Django. [19:24] Interfaces are declared in the "interfaces" dir, "model" then contains the classes that implement those interfaces. [19:24] "browser" holds the view stuff and templates are the html portion. Well, TAL versions of the html. [19:24] Generally, if you want to figure out what's happening with the Python objects or the database layer, look at stuff in the interfaces and model directories.... [19:25] (Read up on Zope Component Architecture to make better sense of those files.) [19:25] ...but we said we want to focus on easy or obvious bugs, which are likely something to do with the web page itself. [19:25] So let's focus on the stuff in templates or browser code. [19:26] Again, this is the stuff that has to do with display on launchpad.net. (Or launchpad.dev if you working locally.) [19:26] That concludes the tour of the code. Any questions on that part? [19:27] Now let's try to understand how we organize bugs on the launchpad project to find something to fix. [19:28] Tagging can help us here. We use "trivial" or "easy" to mark bugs that are pretty shallow. [19:28] Here is a list of 162 Triaged launchpad bugs tagged "trivial" -- [19:28] http://tinyurl.com/6l572gg [19:29] But if you look at those bugs, you can see we often use "trivial" to mean trivial to an *experienced* Launchpad dev. [19:29] So that might be useful, but I like to narrow further, when looking for truly easy stuff. [19:30] Let's search for Triaged bugs with the tag "trivial" and "ui" since I know "ui" is used to many anything in the web page itself. [19:30] http://tinyurl.com/5snjlva [19:30] Now we're down to 69 bugs. :-) [19:31] FWIW, "ui" and "css" and "javascript" are all tags we use for front end work that combined with "easy" or "trivial" tags can help you find easier bugs to fix. [19:32] trivial means (for lp devs) something that can be fixed in an hour. "easy" is a bit longer but still short work. maybe 2-3 hour fix all told. [19:32] You can look through these bugs above if you like, but I've spent some time with them already this morning.... [19:32] ....so I've found a bug that will be a nice one to demo how to approach fixing bugs. [19:33] Let's look at bug 470430 and start working on how to fix Launchpad bugs now. [19:33] https://bugs.launchpad.net/launchpad/+bug/470430 [19:34] This is an older bug that outlines that the icon for the link "Copy packages" is bad. [19:34] See the bug report for a link to a page that has the bad link on it. [19:35] We currently use the edit icon that is used too much on Launchpad, and mpt recommends a new icon or an expander icon. [19:35] But we can also just remove the icon to fix the issue. [19:36] The first thing I would do is simply search the soyuz templates to find the one that has the link for "Copy packages." [19:36] (I know to look in soyuz because I know that's the part of lp that deals with packaging on Launchpad.) [19:37] (If you want to work on an easy bug like this but don't even know where to start, ask in #launchpad-dev here on Freenode.) [19:37] feel free to ping me if no one responds :) [19:37] So back to the bug in question.... [19:37] To find this link, I would change to the devel tree and run: [19:37] grep -rI "Copy packages" lib/lp/soyuz/templates/ [19:38] If you do that, you'll find that it returns nothing. This is a clue that the link is created in Python code rather than a template. [19:38] So I need to look in the browser code I told you about earlier: [19:39] grep -rI "Copy packages" lib/lp/soyuz/browser/ [19:39] This gives me: http://pastebin.ubuntu.com/642798/ [19:40] The "text" and "label" bits there look promising. [19:40] So I now want to open lib/lp/soyuz/browser/archive.py in an editor and see what's happening there. [19:40] We need to search the file for the phrase "Copy packages". [19:41] We can find a function that is called "copy" which creates a link from a class called "Link". This looks like it! [19:41] See the code pasted here: http://pastebin.ubuntu.com/642799/ [19:42] That line also sets the icon to "edit." And this is the cause of our bug. [19:42] So the easy fix is to just remove the icon line and make it like: http://pastebin.ubuntu.com/642801/ [19:42] The fix is at line 5 in the paste. [19:43] And now we've fixed a trivial bug! :-) [19:44] The next steps would be to branch from devel, create your own branch with this fix in it, and push it up to Launchpad. [19:44] Then propose it for merging into lp:launchpad. [19:44] A Launchpad dev should then step in and help you get your changes landed. [19:44] Any questions about all that? [19:46] It really is just that easy to fix easy bugs. :) [19:47] Today we've been through getting setup with lp dev, finding our way around the code base, finding bugs, and learning how to approach fixing easy bugs. [19:47] Please ask around on #launchpad-dev if you'd like to get more involved with launchpad development and try your hand at fixing these kinds of bugs. [19:48] Thanks for attending the session everyone! That's all I have. [19:48] I'll hang around until the next session if any lingering questions arise. }}}