This article describes the entire process of writing, packaging and releasing a new Haskell library. If you love programming Haskell, and want to keep doing so, you’ll write some libraries and release them. The lambda revolution isn’t going to happen without your code!
Creating Data.DList, it took about 60 minutes. People often need O(1) append, so about time we had a library for it. Here’s the entire transcript of creating a new Haskell project and releasing it to a public server. I then created a web page for the project, and announced it on the haskell@ mailing list. I used the following tools:
Ready? Here we go!
Script started on Mon Dec 11 13:47:40 2006
$ cd dons/src
$ mkdir dlist
$ cd dlist
$ mkcabal
Project name: dlist
What license ["GPL","LGPL","BSD3","BSD4","PublicDomain","AllRightsReserved"] ["BSD3"]:
What kind of project [Executable,Library] [Executable]: Library
Is this your name? "Don Stewart " [Y/n]:
Is this your email address? "<dons@cse.unsw.edu.au>" [Y/n]:
Created Setup.lhs and dlist.cabal
$ cp ~/dons/src/yi/Yi/Lexers.hs .
$ ls
Lexers.hs Setup.lhs dlist.cabal
$ mkdir Data
$ mv Lexers.hs Data/DList.hs
$ vim Data/DList.hs
$ vim dlist.cabal
$ darcs init
$ darcs add dlist.cabal Setup.lhs Data/ Data/DList.hs
$ darcs record --all
Shall I record this change? (1/?) [ynWsfqadjkc], or ? for help: a
What is the patch name? Initial import of dlist package
Do you want to add a long comment? [yn]n
Finished recording patch 'Initial import of dlist package'
$ runhaskell Setup.lhs configure --prefix=/home/dons
Setup: Warning: No exposed modules or executables in this package.
Setup: Error: Nonempty library, but empty exposed modules list.
Cabal may not build this library correctly
$ vim dlist.cabal
$ runhaskell Setup.lhs configure --prefix=/home/dons
Configuring dlist0.1...
configure: /home/dons/bin/ghcpkg
configure: Dependency baseany: using base2.0
configure: Using install prefix: /home/dons
configure: Binaries installed in: /home/dons/bin
configure: Libraries installed in: /home/dons/lib/dlist0.1/ghc6.6
configure: Private binaries installed in: /home/dons/libexec
configure: Data files installed in: /home/dons/share/dlist0.1
configure: Using compiler: /home/dons/bin/ghc
configure: Compiler flavor: GHC
configure: Compiler version: 6.6
configure: Using package tool: /home/dons/bin/ghcpkg
configure: Using ar found on system at: /usr/bin/ar
configure: Using haddock found on system at: /home/dons/bin/haddock
configure: No pfesetup found
configure: Using ranlib found on system at: /usr/bin/ranlib
configure: Using runghc found on system at: /home/dons/bin/runghc
configure: Using runhugs found on system at: /home/dons/bin/runhugs
configure: Using happy: /home/dons/bin/happy
configure: Using alex: /home/dons/bin/alex
configure: Using hsc2hs: /home/dons/bin/hsc2hs
configure: No c2hs found
configure: Using cpphs: /home/dons/bin/cpphs
configure: No greencard found
Preprocessing library dlist0.1...
Building dlist0.1...
$ runhaskell Setup.lhs build
Preprocessing library dlist0.1...
Building dlist0.1...
Data/DList.hs:17:2: parse error on input `DList'
$ vim Data/DList.hs +17
$ runhaskell Setup.lhs build
Preprocessing library dlist0.1...
Building dlist0.1...
[1 of 1] Compiling Data.DList ( Data/DList.hs, /usr/obj/cabal/Data/DList.o )
/usr/bin/ar: creating /usr/obj/cabal/libHSdlist0.1.a
$ runhaskell Setup.lhs install
Installing: /home/dons/lib/dlist0.1/ghc6.6 & /home/dons/bin dlist0.1...
Registering dlist0.1...
Reading package info from ".installed-pkg-config" ... done.
Saving old package config file... done.
Writing new package config file... done.
$ darcs amendrecord
Mon Dec 11 14:20:56 EST 2006 Don Stewart <dons@cse.unsw.edu.au>
* Initial import of dlist package
Shall I amend this patch? [yNvpq], or ? for help: y
hunk ./Data/DList.hs 15
module Data.DList
+module Data.DList (
Shall I add this change? (1/?) [ynWsfqadjkc], or ? for help: y
hunk ./dlist.cabal 10
+Exposedmodules: Data.DList
Shall I add this change? (2/?) [ynWsfqadjkc], or ? for help: y
Finished amending patch:
Mon Dec 11 14:21:53 EST 2006 Don Stewart <dons@cse.unsw.edu.au>
* Initial import of dlist package
$ runhaskell Setup.lhs haddock
Preprocessing library dlist0.1...
Running Haddock for dlist0.1...
Warning: cannot use package base2.0:
HTML directory /home/dons/share/ghc6.6/html/libraries/base does not exist.
/usr/obj/cabal/tmp/Data/DList.hs:"/usr/obj/cabal/tmp/Data/DList.hs": 37:1: parse error in doc string: [TokPara]
$ vim Data/DList.hs +37
$ runhaskell Setup.lhs haddock
Preprocessing library dlist0.1...
Running Haddock for dlist0.1...
Warning: cannot use package base2.0:
HTML directory /home/dons/share/ghc6.6/html/libraries/base does not exist.
$ w3m dump dist/doc/html/index.html
dlist0.1: Contents Index
dlist0.1:
Differences lists: lists supporting efficient append
Modules
show/hideData
Data.DList
Produced by Haddock version 0.8
$ mkdir tests
$ vim tests/Properties.hs
$ vim tests/Parallel.hs
$ cd tests
$ runhaskell Properties.hs
2: singleton : OK, 1000 tests.
1: model : OK, 1000 tests.
2: snoc : OK, 1000 tests.
1: append : OK, 1000 tests.
$ cd ..
$ darcs add tests
$ darcs add tests/Parallel.hs tests/Properties.hs
$ darcs whatsnew s
M ./Data/DList.hs 1 +1
A ./tests/
A ./tests/Parallel.hs
A ./tests/Properties.hs
$ darcs record --all
...
Shall I record this change? (6/?) [ynWsfqadjkc], or ? for help: y
What is the patch name? Add QuickChecks
Finished recording patch 'Add QuickChecks'
$ darcs setpref test "cd tests ; runhaskell Properties.hs"
Changing value of test from '' to 'cd tests ; runhaskell Properties.hs'
changepref test
cd tests ; runhaskell Properties.hs
Shall I record this change? (1/?) [ynWsfqadjkc], or ? for help: y
What is the patch name? pre run tests on each commit
Do you want to add a long comment? [yn]n
Running test...
2: singleton : OK, 1000 tests.
2: snoc : OK, 1000 tests.
1: model : OK, 1000 tests.
2: append : OK, 1000 tests.
Test ran successfully.
Looks like a good patch.
Finished recording patch 'run tests on each commit'
$ darcs whatsnew s
No changes!
$ darcs tag
What is the version name? 0.1 dlist 0.1
Finished tagging patch 'TAG dlist 0.1'
$ runhaskell Setup.lhs sdist
Building source dist for dlist0.1...
*** Exception: LICENSE: copyFile: does not exist (No such file or directory)
$ cp ~/pqc/LICENSE .
$ vim LICENSE
$ darcs add LICENSE
$ darcs record
addfile ./LICENSE
Shall I record this change? (1/?) [ynWsfqadjkc], or ? for help: y
...
Shall I record this change? (2/?) [ynWsfqadjkc], or ? for help: y
What is the patch name? add license
Do you want to add a long comment? [yn]n
Running test...
2: singleton : OK, 1000 tests.
2: snoc : OK, 1000 tests.
1: model : OK, 1000 tests.
2: append : OK, 1000 tests.
Test ran successfully.
Looks like a good patch.
Finished recording patch 'add license'
$ vim README
$ darcs add README
$ darcs record --all
What is the patch name? Add a readme
Do you want to add a long comment? [yn]n
Running test...
2: singleton : OK, 1000 tests.
2: snoc : OK, 1000 tests.
1: model : OK, 1000 tests.
2: append : OK, 1000 tests.
Test ran successfully.
Looks like a good patch.
Finished recording patch 'Add a readme'
$ ls
Data LICENSE README Setup.lhs _darcs dist dlist.cabal tests
$ darcs dist d dlist0.1.
Created dist as dlist0.1.tar.gz
$ darcs whatsnew s
No changes!
$ darcs put pill00.cse.unsw.edu.au:/home/chakcvs/darcs/dlist/
Finished applying...
Script done on Mon Dec 11 15:04:54 2006