Monday, May 20, 2013

easy way to maintain source code decorum


It's best to maintain source code in a clean, pretty state. It's easy to read, and more importantly easy to find small code changes that might lead to dramatic effects.
But, during development, people add debugging statements. Print statements, debug logging, and things like "# XXX fix this".  Letting this code hit production is not good, as it confuses the normal operation of the system.

To pick bits of debugging fluff from your code, add this to your top-level Makefile.  Before merging your code with the main branch, run "make sniff" to sniff your code for unwantedly smelly bits, like leftover debugging code.

The following will only check newly-changed code, and won't warn on old smelly code:

sniff:
git diff develop | awk '/(debug|XXX)/ { print $$1; found=1; } END { exit found }'

If this is run as part of a Jenkins job it'll flag stinky code as an error. 

trivial Jenkins configuration

Knowing when your software breaks is useful. If you catch subtle errors soon after the change, it's *much* easier to figure out which bit of code "optimization" broke things for the users.

Another benefit is fixing "works for me" syndrome. Even if you're building software just for yourself, it's nice to have a 3rd party to verify that you didn't do silly things. Forgetting to check in South database changes is quite easy, but that simple omission will break everything.

Jenkins is a cranky to set up, because it's a collection of moving parts. The best setup would be having Jenkins rebuild your tests every time GitHub detects a source code change.

The following setup is not as geeky, but it's much, much easier: tell Jenkins copy local source files and test, every now and then.


  1. go to Jenkins on your local computer: http://localhost:8080/
  2. New Job ("free-style software project")
  3. You're now on the Configure page. click Add Build Step.
  4. Execute Shell
  5. adjust Makefile to your liking
  6. run the test every few minutes

For #4, in the Command area, type this little script:


rsync -av --delete --exclude='.git' MYSOURCEDIR $WORKSPACE
make -C $WORKSPACE test

Replace MYSOURCEDIR with your source directory -- the full path. For me it's /home/johnm/work/yed.   The above copies source from your normal development area to the job-specific Jenkins area.  It strips files that have been deleted in the source tree

In step #5, put a Makefile with a "test" verb in the top of your source code. I'm running Django, so to test the project I want to run the Django test suite on my main app.


test:
./manage.py test -v1

Remember to use the TAB key instead of spaces on the 2nd line.

At this stage, test your Jenkins job.  On the Job screen click Configure on the left to return to the Configuration page.  Edit the job, but don't press Save at the bottom of the page -- press Apply.  Open your job in a second browser window.  Click Build Now to start the job, wait for a few seconds, then click the new link which appears in the Build History section of the page.

If it's not perfect, go back to the Configuration page, make changes, press Apply; switch to the Project browser window, click Build Now again.  This workflow lets you rapidly make changes to your Jenkins project without having lots of windows open.


Step 6: Once #1-5 above is working to your satisfaction, you can automate the test.  On the Job Configure screen, in the Build Triggers section, enable "Build periodically".  In the text area, type this schedule:

H/15 * * * *

This means run your test every 15 minutes, no matter if anything has changed or not.  The "H" is to not overwhelm your system if lots of tests are running at once.



As an alternate for #5, just to make sure things are running, you can use the following Makefile instead:

test:
echo 'out of beer!' ; false

When you run the Jenkins job on this, the test will fail because the "false" command returns a status of 1. This proves that Jenkins sees your code, is copying to the right place, and is running your Makefile test command.