Reading darcs

See also http://www.haskell.org/haskellwiki/How_to_read_Haskell

Helper functions

Ever wonder what functions like wspfr and jn do? Here's a hint: helper functions in the darcs code are often just named by taking the first letter of the function they are supposed to help. So, for example, wnpfr is just a helper function to with_selected_patches_from_repository.

liftM/fmap

Darcs uses liftM and fmap a lot (more fmap than liftM). In fact, darcs hacking is how I eventually managed to understand what they do. Here's a hint: the following three bits of code do the same thing:

-- using do notation
do foo <- someMonadicThing
   return (myFn foo)

-- using liftM
liftM myFn someMonadicThing

-- using liftM as an operator
myFn `liftM` someMonadicThing

I like that third one; it helps me think of liftM as a monadic $

Coding

Use Workaround

Some stuff from the standard library, such as createDirectoryIfMissing or getCurrentDirectory only appeared very recently (ghc 6.4.1?). But you can still use them! The only trick is to import them from Workaround instead of from the regular place. If you have a recent ghc, then it's the same thing, and if you have an older one, the configure script puts in an implementation to plug the gap.

Testing and Debugging

The darcs regression testing system is very handy. Basically, any file in tests/ which ends in .pl or .sh is run via the test harness. The following is a collection of tips and tricks for making full use of this test system.

Get a more forgiving Makefile

When debugging something tricky, it's sometimes useful to comment out bits and pieces of darcs. But then, whenever you try to recompile something, GHC complains about something being defined, but not used. Sometimes, rather than backtracking your way through and commenting everything you don't need, it's just simpler to edit the GNUMakefile...

-GHCFLAGS += -Wall -Werror -I.
+GHCFLAGS += -Wall -I.

But don't forget to change this back before you submit any patches! -Werror is really useful for making sure that errors don't sneak into the code.

Faster edit-compile cycle

You can disable all optimization options to speed up the compilation process considerably, just remove the -O2 from the GHCFLAGS        := ... line in autoconf.mk. Using ghci is even faster, here is the commandline that works on my system:

ghci -cpp  -I. -DHAVE_CURSES -DHAVE_CURL  -package parsec -optl-
lcurl -optl-lssl -optl-lcrypto -optl-lz -optl-lcurses  darcs.lhs
maybe_relink.o atomic_create.o hscurl.o umask.o c_compat.o fpstring.o

You can use e.g. :main pull --set-default for testing.

Note that on a Mac you will have to run 'CFLAGS=-mmacosx-version-min=10.4 ./configure' before running ghci in order to properly transform the symbols.

Running a subset of tests

Sometimes you just want to see if a small handful of tests are working. You can do this by creating a file tests/tests_to_run with the filenames of the tests you want to run. Then you just run make test as normal and only the tests in that file will be performed. Note that this does *not* affect the posthook tests.

Dealing with different filesystems

These are written for a Mac, but I'm sure the equivalent techniques exist under linux.

Say you're on a Mac, and you want to see how darcs would behave with a case sensitive file system like what Linux has. More precisely, you want to run darcs's regression tests but on a different filesystem. Here is a trick I use:

  1. create and mount disk image

    hdiutil create -size 3M -fs UFS -volname darcsTest darcsTest
    open darcsTest.dmg
    
  2. set up the test image

    cd /Volumes/darcsTest
    # link the darcs binary
    ln -s YOUR_CODING_DIR/darcs darcs
    mkdir test
    
  3. you might consider unmounting and backing up the dmg for future use... remount it...
  4. move away your tests directory (save your test files first! close your text editor!)

    cd YOUR_CODING_DIR
    mv test orig_tests
    ln -s /Volumes/darcsTest/tests tests
    
  5. test away!

    cp -R orig_tests/* tests
    make test
    

Note: if you plan on switching back and forth alot, don't bother mv'ing orig_tests back to tests; just make a symlink rm tests; ln -s orig_tests tests. Another trick to prevent confusion is to always edit your tests in orig_tests and copy them over. It helps me from confusing myself because I always know that orig_tests is the correct copy.

Playing around with your darcs

I like to have my development darcs in the command line, so for example, in my .cshrc, I have something like

alias mydarcs ${HOME}/darcsHacking/darcs

I guess the equivalent in bash would be

alias mydarcs=${HOME}/darcsHacking/darcs

Keeping track of branches

It's often useful to have at least two branches on your computer, one for unstable, and one for your own use. Here's how mine is set up for easy pulling and reduced disk usage.

cd ~/darcsHacking
darcs get http://www.darcs.net/repos/unstable
darcs get unstable me-darcs
cd unstable/_darcs/prefs
wget http://www.darcs.net/repos/unstable/_darcs/prefs/email

This way, when you do a darcs send from me-darcs, it tries to send to your local unstable and succesfully finds out which email address to sends it to. Occasionally I do a darcs pull from unstable, and then a darcs pull from me-darcs to propagate the patch.

Keep some sample repositories around

One thing you might notice yourself doing a lot is creating lots of foobar repositories for testing simple darcs properties. It may save you a bit of time to create those repositories once and use them for further playing around

cd ~/darcsHacking
mkdir examples
cd examples
mkdir foobar
cd foobar
darcs init
touch foo
darcs add foo
darcs record
# etc etc

And then in the future, you can just do

cd /tmp
darcs get ~/darcsHacking/examples/foobar

Bugs and tests

Distilling test cases

Sometimes really helpful people submit buggy repos to the tracker along with a patch bundle they couldn't apply. Tricks

Testing SSH stuff

Testing SSH stuff can be tricky to automate (although I might have one or two ideas up my sleeves). Below are some ideas to ease the pain of manual testing. Some more notes can be found at SSHNotes

Setting up SSH stuff

  1. Avoid SSH passphrase stuff - you want to simulate a regular user interacting with the underlying ssh command. Add an entry to your .ssh/config which disables public key authentication for a specific host that you invent. For example, I have a host foo.pw which is really configured to connect to foo.com without public key authentication and with fewer password retries. This lets me do stuff like darcs get me@foo.pw:sampleRepo:

    Host foo.pw
    HostName foo.com
            PasswordAuthentication yes
            PubkeyAuthentication no
            NumberOfPasswordPrompts 2
    
  2. Use a shell script to automate setting up of repositories that you need. See tests/ssh_test

Log your ssh calls

  1. Create the scripts /tmp/chattyssh, /tmp/chattyscp, /tmp/chattysftp:

    #!/bin/sh
    SCMD=ssh
    echo ${SCMD} "$@" >> /tmp/ssh-log
    ${SCMD} "$@"
    
  2. Tell darcs to use chatty sshes

    export DARCS_SSH=/tmp/chattyssh
    export DARCS_SCP=/tmp/chattyscp
    export DARCS_SFTP=/tmp/chattysftp
    

DarcsWiki: DeveloperTips (last edited 2008-03-11 17:31:02 by EricKow)