747 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			747 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| <!-- hledger repo and http://hledger.org versions of this document are periodically bidirectionally synced -->
 | |
| 
 | |
| * toc
 | |
| 
 | |
| # Developer guide
 | |
| 
 | |
| Contributors of all levels are most welcome in the hledger project.
 | |
| This guide is action-oriented: below you'll find useful links, then procedures, then general info.
 | |
| 
 | |
| ## Quick links
 | |
| 
 | |
| <style>
 | |
| tr {
 | |
|     border-top:thin solid #bbb;
 | |
| }
 | |
| </style>
 | |
| <!-- | hledger.org   | [combined release notes](release notes), [pre-compiled binaries](download) | -->
 | |
| <!-- [web ui demo](http://demo.hledger.org/register?q=inacct%3Aassets%3Abank%3Achecking+sym%3A\%24) -->
 | |
| <!-- [](https://travis-ci.org/simonmichael/hledger) -->
 | |
| <!-- [](http://packdeps.haskellers.com/feed?needle=hledger) -->
 | |
| <!-- [](http://bugs.hledger.org) -->
 | |
| <!-- [](https://github.com/simonmichael/hledger/issues?q=label:bounty) -->
 | |
| |
 | |
| |-------------------------|----------------------------------------------------------------------------|
 | |
| | IRC                     | Join [#hledger](http://hledger.org/irc) ([chat log](http://ircbrowse.net/browse/hledger); see also [#ledger](http://webchat.freenode.net?channels=ledger&randomnick=1)) |
 | |
| | Mail list               | [list.hledger.org](http://list.hledger.org) ([Gmane](http://dir.gmane.org/gmane.comp.finance.ledger.hledger)) |
 | |
| | Twitter                 | [#ledgercli](https://twitter.com/search?q=%23ledgercli&src=typd&f=realtime), <a href="https://twitter.com/ledgertips">@LedgerTips</a> |
 | |
| | hledger-web demo          | [demo.hledger.org](http://demo.hledger.org) |
 | |
| | Trello                  | [backlog/wishlist planning board](http://hledger.org/trello) |
 | |
| | Github                  | [simonmichael/hledger](http://github.com/simonmichael/hledger) (code.hledger.org) <br> [](https://travis-ci.org/simonmichael/hledger), [hydra build status](http://hydra.cryp.to/jobset/hledger/master#tabs-jobs) <br> [commits](http://github.com/simonmichael/hledger/commits), [unreleased commits](https://github.com/simonmichael/hledger/compare/0.23...master), [release branch commits](https://github.com/simonmichael/hledger/compare/master...0.23), [COMMITS](http://starlogs.net/#simonmichael/hledger) <br> [open bugs](https://github.com/simonmichael/hledger/issues?direction=desc&labels=BUG&page=1&sort=created&state=open), [open issues](https://github.com/simonmichael/hledger/issues?direction=desc&labels=&page=1&sort=created&state=open) [](https://github.com/simonmichael/hledger/issues?direction=desc&labels=&page=1&sort=created&state=open) , <a href="https://github.com/simonmichael/hledger/issues?q=label:bounty">issues with bounties</a> [](https://github.com/simonmichael/hledger/issues?q=label:bounty)<!-- , <a href="https://www.bountysource.com/trackers/536505-simonmichael-hledger">hledger @ bountysource.com</a> -->, [all issues](https://github.com/simonmichael/hledger/issues?direction=desc&labels=&page=1&sort=created) |
 | |
| | Hackage                 | packages: [hledger-lib](http://hackage.haskell.org/package/hledger-lib), [hledger](http://hackage.haskell.org/package/hledger), [hledger-web](http://hackage.haskell.org/package/hledger-web), [hledger-diff](http://hackage.haskell.org/package/hledger-diff), [hledger-interest](http://hackage.haskell.org/package/hledger-interest), [hledger-irr](http://hackage.haskell.org/package/hledger-irr), [hledger-vty](http://hackage.haskell.org/package/hledger-vty), [hledger-chart](http://hackage.haskell.org/package/hledger-chart), [\*hledger\*](http://hackage.haskell.org/packages/search?terms=hledger) <!-- [](http://hackage.haskell.org/package/hledger) --> <br> build history/GHC compatibility: [hledger-lib](http://matrix.hackage.haskell.org/package/hledger-lib), [hledger](http://matrix.hackage.haskell.org/package/hledger), [hledger-web](http://matrix.hackage.haskell.org/package/hledger-web)  <br> [](http://packdeps.haskellers.com/feed?needle=hledger) [hledger-lib](http://packdeps.haskellers.com/feed/?needle=hledger-lib), [hledger](http://packdeps.haskellers.com/feed/?needle=hledger), [hledger-web](http://packdeps.haskellers.com/feed/?needle=hledger-web) <br> reverse dependencies: [hledger-lib](http://packdeps.haskellers.com/reverse/hledger-lib), [hledger](http://packdeps.haskellers.com/reverse/hledger) |
 | |
| | Stackage                | [hledger entry](https://github.com/fpco/stackage/blob/master/Stackage/Config.hs#L449-450), [issues](https://github.com/fpco/stackage/search?q=hledger&ref=cmdform&type=Issues) <br> [jenkins build status](http://jenkins.stackage.org/job/Stackage/), last build output: [7.4](http://jenkins.stackage.org/job/Stackage/ghcversion=7.4.2/lastBuild/console), [7.6](http://jenkins.stackage.org/job/Stackage/ghcversion=7.6.3/lastBuild/console), [7.8](http://jenkins.stackage.org/job/Stackage/ghcversion=7.8.2/lastBuild/console), [7.10](http://jenkins.stackage.org/job/Stackage/ghcversion=7.10.1/lastBuild/console) |
 | |
| | Debian                  | source packages <br> [haskell-hledger-lib](http://packages.qa.debian.org/h/haskell-hledger-lib.html), [bugs](https://bugs.debian.org/cgi-bin/pkgreport.cgi?package=haskell-hledger-lib), [haskell-hledger](http://packages.qa.debian.org/h/haskell-hledger.html), [bugs](https://bugs.debian.org/cgi-bin/pkgreport.cgi?package=haskell-hledger), [haskell-hledger-web](http://packages.qa.debian.org/h/haskell-hledger-web.html), [bugs](https://bugs.debian.org/cgi-bin/pkgreport.cgi?package=haskell-hledger-web) <br> binary packages <br> testing: [hledger](https://packages.debian.org/testing/hledger), [bugs](https://bugs.debian.org/cgi-bin/pkgreport.cgi?package=hledger;dist=testing), [hledger-web](https://packages.debian.org/testing/hledger-web), [bugs](https://bugs.debian.org/cgi-bin/pkgreport.cgi?package=hledger-web;dist=testing) <br> unstable: [hledger](https://packages.debian.org/unstable/hledger), [bugs](https://bugs.debian.org/cgi-bin/pkgreport.cgi?package=hledger;dist=unstable), [hledger-web](https://packages.debian.org/unstable/hledger-web), [bugs](https://bugs.debian.org/cgi-bin/pkgreport.cgi?package=hledger-web;dist=unstable) <br> all: [\*hledger\*](https://packages.debian.org/search?searchon=names&keywords=hledger) <br> popularity stats: [hledger](https://qa.debian.org/popcon.php?package=haskell-hledger), [hledger-web](https://qa.debian.org/popcon.php?package=haskell-hledger-web) <br> [PTS help](https://www.debian.org/doc/manuals/developers-reference/resources.html#pkg-tracking-system) |
 | |
| | Ubuntu                  | source packages <br> [haskell-hledger-lib](https://launchpad.net/ubuntu/+source/haskell-hledger-lib), [bugs](https://bugs.launchpad.net/ubuntu/+source/haskell-hledger-lib), [haskell-hledger](https://launchpad.net/ubuntu/+source/haskell-hledger), [bugs](https://bugs.launchpad.net/ubuntu/+source/haskell-hledger), [haskell-hledger-web](https://launchpad.net/ubuntu/+source/haskell-hledger-web), [bugs](https://bugs.launchpad.net/ubuntu/+source/haskell-hledger-web) <br> binary packages <br> [\*hledger\*](http://packages.ubuntu.com/search?suite=all&searchon=names&keywords=hledger) |
 | |
| | Gentoo                  | [hledger](http://gpo.zugaina.org/dev-haskell/hledger), [hledger-web](http://gpo.zugaina.org/dev-haskell/hledger-web), [\*hledger\*](http://gpo.zugaina.org/Search?search=hledger) |
 | |
| | Fedora                  | [hledger](https://apps.fedoraproject.org/packages/hledger), [\*hledger\*](https://apps.fedoraproject.org/packages/s/hledger), [hledger (package db)](https://admin.fedoraproject.org/pkgdb/package/hledger/), [Haskell SIG](http://fedoraproject.org/wiki/Haskell_SIG) |
 | |
| 
 | |
| <!-- list the debian packages for clarity:
 | |
| 3 source:
 | |
| haskell-hledger-lib
 | |
| haskell-hledger
 | |
| haskell-hledger-web
 | |
| 8 binary:
 | |
| hledger
 | |
| hledger-web
 | |
| libghc-hledger-dev
 | |
| libghc-hledger-doc
 | |
| libghc-hledger-prof
 | |
| libghc-hledger-lib-dev
 | |
| libghc-hledger-lib-doc
 | |
| libghc-hledger-lib-prof
 | |
| -->
 | |
| 
 | |
| <!-- old/future links -->
 | |
| <!-- [haddock coverage](http://hledger.org/profs/haddock-coverage), -->
 | |
| <!-- [unit test coverage](http://hledger.org/profs/coverage/hpc_index_fun.html), -->
 | |
| <!-- [benchmark](http://hledger.org/profs/latest.bench) -->
 | |
| <!-- [profile](http://hledger.org/profs/latest.prof), -->
 | |
| <!-- [heap](http://hledger.org/profs/latest.ps) -->
 | |
| <!-- [developer notes](http://github.com/simonmichael/hledger/NOTES.org)\ -->
 | |
| <!-- [browse dev API docs](http://hledger.org/api/frames.html) -->
 | |
| <!-- [How to clone it](developer-guide#set-up-for-development) -->
 | |
| <!-- [hledger-web dev demo](http://demo.hledger.org:5001) -->
 | |
| 
 | |
| <!-- hoogle search form
 | |
| <script type="text/javascript" src="http://haskell.org/hoogle/datadir/resources/jquery-1.4.2.js"></script>
 | |
| <script type="text/javascript" src="http://haskell.org/hoogle/datadir/resources/hoogle.js"></script>
 | |
| <form action="http://haskell.org/hoogle/" method="get" style="display:inline; margin:0; padding:0;">
 | |
| <input type="hidden" name="prefix" value="+hledger +hledger-lib +hledger-web +hledger-vty +hledger-chart" />
 | |
| <span style="white-space:nowrap;"
 | |
| ><input type="text" name="hoogle" id="hoogle" accesskey="1" size="30"
 | |
| /><input type="submit" value="search API with hoogle"
 | |
| /></span>
 | |
| </form>
 | |
| -->
 | |
| 
 | |
| 
 | |
| ## How to..
 | |
| 
 | |
| Here are some suggested procedures to help you quickly (re)engage
 | |
| with the project and get things done.
 | |
| 
 | |
| ### Suggest enhancements
 | |
| 
 | |
| Suggestions and feature requests (aka wishes) are very welcome, but we
 | |
| don't want them to pile up in the issue tracker obscuring bugs and
 | |
| higher-priority tasks. So before opening a github issue, first consider:
 | |
| 
 | |
| 1. The [#hledger](http://irc.hledger.org) (irc.hledger.org) IRC channel on freenode
 | |
|    and the [mail list](http://list.hledger.org) (list.hledger.org) are excellent places for discussing and refining ideas.
 | |
|    Both are archived and linkable, so the idea won't be lost. IRC is quick (if I'm not online, leave a comment anyway),
 | |
|    while the mail list has the most readers.
 | |
| 2. The [trello board](http://trello.hledger.org) (trello.hledger.org) is a good place
 | |
|    for storing and prioritising backlog and wishlist items of all kinds.
 | |
| 3. The [bug tracker](http:///bugs.hledger.org) (bugs.hledger.org) on github
 | |
|    is best used for issues with the existing product or docs. If you're not sure if you're reporting
 | |
|    a bug or not, it's fine to post it here.
 | |
| 
 | |
| When wishes land in the bug tracker, they get the WISH label, and
 | |
| these are excluded from the default view given by bugs.hledger.org.
 | |
| 
 | |
| ### Report problems
 | |
| 
 | |
| - for quick help or if you're not sure about the problem,
 | |
|   you can ask on the [#hledger](http://irc.hledger.org) (irc.hledger.org) IRC channel
 | |
|   or the [mail list](http://list.hledger.org) (list.hledger.org).
 | |
|   If #hledger does not respond quickly, you can leave the window open and check back later, or leave your email address.
 | |
| - check the open and closed issues in the [bug tracker](http://bugs.hledger.org) (bugs.hledger.org). Sometimes the problem has been fixed in git but not yet released.
 | |
| - report new issues in the bug tracker (shortcut: [bugs.hledger.org/new](http://bugs.hledger.org/new))
 | |
| 
 | |
| <!-- - test and share problem journal snippets at paste . hledger.org -->
 | |
| 
 | |
| ### Help with testing
 | |
| 
 | |
| - review and test our documentation and web presence
 | |
| - download and test the binaries on your platform
 | |
| - test installing via cabal
 | |
| - use the tools and test functionality, usability, browser compatibility, ui layout etc.
 | |
| - check that `hledger test` reports no failures
 | |
| - [run the developer tests](#how-to-run-the-tests)
 | |
| - discuss/report problems via irc/mail list/bug tracker
 | |
| 
 | |
| ### Help with bug tracking
 | |
| 
 | |
| - get to know the [bug tracker](http://bugs.hledger.org) and its contents
 | |
| - research and update issues
 | |
| - some convenient url shortcuts:\
 | |
|   [`bugs.hledger.org`](http://bugs.hledger.org)\
 | |
|   [`bugs.hledger.org/new`](http://bugs.hledger.org/new)\
 | |
|   `bugs.hledger.org/N`
 | |
| 
 | |
| ### Set up for development
 | |
| 
 | |
| 1. Download and install [stack](https://github.com/commercialhaskell/stack/wiki/Downloads).
 | |
|    This builds haskell projects and can also install GHC (and on windows, git) if needed.
 | |
| 2. Get the hledger repo:
 | |
| 
 | |
|     ```{.shell .bold}
 | |
|     $ git clone https://github.com/simonmichael/hledger.git
 | |
|     $ cd hledger
 | |
|     ```
 | |
| 
 | |
| 3. Install [GNU Make](http://www.gnu.org/software/make) and other optional extra tools (see the Makefile for a list):
 | |
| 
 | |
|     ```shell
 | |
|     $ stack install shelltestrunner hasktags profiteur hpack
 | |
|     ```
 | |
| 
 | |
| 4. Run `make` or `stack --help` to see some suggested commands:
 | |
| 
 | |
|     ```{.shell .bold}
 | |
|     $ make
 | |
|     Makefile:37: -------------------- hledger make rules --------------------
 | |
|     Makefile:39: make [help] -- list documented rules in this makefile. make -n RULE shows more detail. 
 | |
|     Makefile:204: (INSTALLING:)
 | |
|     Makefile:206: make install -- download dependencies and install hledger executables to ~/.local/bin or equivalent (with stack)
 | |
|     Makefile:231: (BUILDING:)
 | |
|     Makefile:235: make build -- download dependencies and build hledger executables (with stack)
 | |
|     Makefile:304: make hledgerdev -- quickly build the hledger executable (with ghc and -DDEVELOPMENT) 
 | |
|     ...
 | |
|     $ stack --help
 | |
|     Available commands:
 | |
|       build                    Build the project(s) in this directory/configuration
 | |
|       install                  Build executables and install to a user path
 | |
|       test                     Build and test the project(s) in this
 | |
|                                directory/configuration
 | |
|       bench                    Build and benchmark the project(s) in this
 | |
|                                directory/configuration
 | |
|     ...
 | |
|     ```
 | |
| 
 | |
| Old instructions:
 | |
| 
 | |
| 1. Get [GHC](https://www.haskell.org/ghc/) and [cabal-install](http://hackage.haskell.org/package/cabal-install) installed.
 | |
|    I recommend the [stackage.org install guide](http://www.stackage.org/install).
 | |
|    You can see which GHC versions are officially supported in the `tested-with` field in
 | |
|    [hledger.cabal](http://hackage.haskell.org/package/hledger/hledger.cabal)
 | |
|    and
 | |
|    [hledger-web.cabal](http://hackage.haskell.org/package/hledger-web/hledger-web.cabal).
 | |
|    Older versions may also work.
 | |
| 2. Get [git](http://git-scm.com) installed.
 | |
| 3. Get [GNU Make](http://www.gnu.org/software/make) installed (unless you don't care about the Makefile's conveniences).
 | |
|    On some platforms the command will be eg `gmake` instead of `make`.
 | |
| 4. Get the hledger repo:
 | |
| 
 | |
|     ```shell
 | |
|     $ git clone https://github.com/simonmichael/hledger.git
 | |
|     ```
 | |
| 
 | |
| 5. You might want to install or upgrade some of these haskell developer tools.
 | |
|    If you're not sure, skip this step and return to it as needed.
 | |
|    Be sure the cabal bin directory where these are installed (eg ~/.cabal/bin) is in your PATH.
 | |
| 
 | |
|     ```{.shell .bold}
 | |
|     $ cabal update
 | |
|     $ cabal install alex happy       # if you get alex/happy-related errors when building hledger
 | |
|     $ cabal install haddock          # needed to build hledger API docs
 | |
|     $ cabal install shelltestrunner  # needed to run hledger functional tests (may need latest git version)
 | |
|     $ cabal install hoogle hlint     # maybe useful for searching API docs and checking code
 | |
|     ```
 | |
| 
 | |
|     You'll also want a comfortable code editor, preferably with Haskell support.
 | |
|     (I use emacs + [haskell-mode](https://github.com/haskell/haskell-mode),
 | |
|     or occasionally [IntelliJ IDEA](https://www.jetbrains.com/idea/download) + one of the [plugins](https://www.google.com/search?hl=en&q=intellij+plugins+haskell)).
 | |
| 
 | |
| 6. Install haskell libs required by hledger:
 | |
| 
 | |
|     ```{.shell .bold}
 | |
|     $ cd hledger
 | |
|     $ cabal sandbox init   # optional
 | |
|     $ make installdeps     # or cabal install --only-dep ./hledger-lib ./hledger [./hledger-web]
 | |
|     ```
 | |
| 
 | |
|     This will install the required dependencies from Hackage.
 | |
|     If you're new to cabal, you can expect problems at this stage.
 | |
|     The usual remedy is to ensure you start with a clean package db, eg by doing `cabal sandbox init`.
 | |
|     You can simplify and speed up this step a lot by commenting out
 | |
|     hledger-web in the `PACKAGES` list in the [Makefile](https://github.com/simonmichael/hledger/blob/master/Makefile#L41).
 | |
| 
 | |
| 7. Build with cabal:
 | |
| 
 | |
|     ```shell
 | |
|     $ make cabalbuild
 | |
|     ```
 | |
| 
 | |
|     (Tip: `make cabalCMD` runs `cabal CMD` in each of the hledger packages).
 | |
| 
 | |
| 8. Build with GHC:
 | |
| 
 | |
|     ```shell
 | |
|     $ make bin/hledgerdev
 | |
|     ```
 | |
| 
 | |
|     This builds hledger (and hledger-lib) with GHC directly, without using cabal,
 | |
|     and as quickly as possible, without optimizations (the "dev" suffix is a reminder of this).
 | |
|     I use and recommend this method for development, as it crosses package boundaries and ensures you are building the latest code.
 | |
|     However it needs some files generated by cabal build, which is why we did that first.
 | |
| 
 | |
| 
 | |
| ### Get your changes accepted
 | |
| 
 | |
| Follow the usual github workflow:
 | |
| 
 | |
| - fork the main hledger repo on github,
 | |
| - git clone it to your local machine,
 | |
| - git commit, after (?) pulling and merging the latest upstream changes
 | |
| - git push back to github,
 | |
| - open a pull request on github,
 | |
| - follow up on any discussion there.
 | |
| 
 | |
| If you're new to this process, [help.github.com](http://help.github.com) may be useful.
 | |
| 
 | |
| ### Improve the documentation
 | |
| 
 | |
| - get familiar with the website and documentation online, review and test
 | |
| - get familiar with the site/doc source files (see Makefile)
 | |
| - set up for hledger development
 | |
| - send patches with names prefixed with "doc: " (or "site: ")
 | |
| 
 | |
| ### Use the REPL (GHCI)
 | |
| 
 | |
| These all work from the main hledger source directory (at least).
 | |
| 
 | |
| First, ensure all required dependencies are installed with these
 | |
| commands. (You might also need to install some system libs like
 | |
| terminfo or curses.)
 | |
| 
 | |
| ```{.shell .bold}
 | |
| $ stack test
 | |
| $ stack bench
 | |
| ```
 | |
| 
 | |
| Get a GHCI prompt for hledger-lib:
 | |
| ```{.shell .bold}
 | |
| $ stack ghci hledger-lib
 | |
| ```
 | |
| 
 | |
| Get a GHCI prompt for hledger:
 | |
| ```{.shell .bold}
 | |
| $ stack ghci hledger
 | |
| ```
 | |
| 
 | |
| Get a GHCI prompt for hledger-web:
 | |
| ```{.shell .bold}
 | |
| $ stack ghci hledger-web
 | |
| ```
 | |
| hledger-web also needs to find some things in its current directory (like the static/ directory).
 | |
| This normally just works, if not please [send details](https://github.com/simonmichael/hledger/issues/274).
 | |
| 
 | |
| Get a GHCI prompt for hledger and hledger-lib:
 | |
| ```{.shell .bold}
 | |
| $ make ghci
 | |
| ```
 | |
| 
 | |
| Get a GHCI prompt for hledger-web, hledger and hledger-lib:
 | |
| ```{.shell .bold}
 | |
| $ make ghci-web
 | |
| ```
 | |
| 
 | |
| <!--
 | |
| For the dev.hs developer script:
 | |
| ```{.shell .bold}
 | |
| $ make ghci-dev
 | |
| ```
 | |
| -->
 | |
| 
 | |
| ### Run the tests
 | |
| 
 | |
| This command will install haskell dependencies (you might need to
 | |
| install additional system dependencies yourself) and run the package
 | |
| test suites.  Currently these consist of hledger-lib's unit tests,
 | |
| hledger's unit tests, and hledger-web's functional tests:
 | |
| 
 | |
| ```shell
 | |
| $ stack test [PKG]
 | |
| ```
 | |
| 
 | |
| Run the hledger-lib and hledger unit tests as a built-in hledger command:
 | |
| ```shell
 | |
| $ [stack exec] hledger test
 | |
| ```
 | |
| 
 | |
| Run the hledger functional tests:
 | |
| ```{.shell .bold}
 | |
| $ stack install shelltestrunner  # if not already done
 | |
| $ make functest
 | |
| ```
 | |
| 
 | |
| Run both unit and functional tests:
 | |
| ```{.shell .bold}
 | |
| $ make test
 | |
| ```
 | |
| 
 | |
| Test haddock doc generation:
 | |
| ```shell
 | |
| $ make haddocktest
 | |
| ```
 | |
| 
 | |
| 
 | |
| ### Add a test
 | |
| 
 | |
| - identify what to test
 | |
| - choose the test type: unit ? functional ? benchmark ?
 | |
| - currently expected to pass or fail ?
 | |
| - figure out where it goes
 | |
| - write test, verify expected result
 | |
| - get it committed
 | |
| 
 | |
| ### Fix a bug or add a feature
 | |
| 
 | |
| - research, discuss, validate the issue/feature on irc/list/bug tracker
 | |
| - look for related tests, run the tests and check they are passing
 | |
| - add a test ?
 | |
| - develop a patch
 | |
| - include any related issue numbers in the patch name, eg: "fix for blah blah (#NNN)"
 | |
| - get it committed
 | |
| 
 | |
| ### Become a contributor
 | |
| 
 | |
| - after getting one or more patches committed, read and sign the [contributor list & agreement](contributors.html)
 | |
| - or, [ask](#how-to-get-help) to be added
 | |
| 
 | |
| ### Do code review
 | |
| 
 | |
| - review and discuss new pull requests and commits on github
 | |
| - set up for development and test the latest changes in your own repo
 | |
| - read the existing [code docs and source](#quick-links)
 | |
| - send feedback or discuss via irc or list
 | |
| 
 | |
| ### Help with packaging
 | |
| 
 | |
| - package hledger for linux distros, macports, etc.
 | |
| - develop mac/windows installers
 | |
| - find and assist distro packagers/installer developers
 | |
| 
 | |
| ### Help with project management
 | |
| 
 | |
| - clarify/update goals and principles
 | |
| - monitor, report on project progress and performance
 | |
| - research, compare and report on successful projects, related projects
 | |
| - identify collaboration opportunities
 | |
| - marketing, communication, outreach
 | |
| - release management, roadmap planning
 | |
| 
 | |
| ### Do a major release
 | |
| 
 | |
| - review the release how-to in the developer guide
 | |
|     - and update as needed
 | |
|       (make site-preview, http://localhost:8000/developer-guide.html#do-a-major-release)
 | |
| 
 | |
| - clean working copy
 | |
|     - commit/stash/clear any pending changes in working copy
 | |
|     - merge any commits from other branches & working copies
 | |
|     - check out master, or release branch.
 | |
|       Major releases are done in master if possible.
 | |
|       If not, do as much of the below as is feasible in master,
 | |
|       then start a release branch (git checkout -b X.Y)
 | |
| 
 | |
| - ensure tests pass
 | |
|     - make unittest
 | |
|     - make functest
 | |
|     - make haddocktest
 | |
|     - make cabalfiletest
 | |
| 
 | |
| - update dependencies
 | |
|     - check & fix any outdated upper bounds
 | |
|       (dev guide -> quick links -> hackage)
 | |
| 
 | |
| - update cabal files
 | |
|     - */hledger*.cabal
 | |
|         - descriptions
 | |
|         - tested-with
 | |
|         - file lists
 | |
|             - data-files
 | |
|             - extra-tmp-files
 | |
|             - extra-source-files
 | |
|             - exposed-modules
 | |
|             - other-modules
 | |
| 
 | |
| - update stack.yaml file
 | |
|     - resolver
 | |
|     - extra-deps
 | |
|     - flags
 | |
| 
 | |
| - update docs
 | |
|     - haddocks
 | |
|     - */CHANGES
 | |
|     - doc/site/release-notes.md
 | |
|     - doc/contributors.md
 | |
|     - doc/manual.md (commands, options, --help, ledger compatibility..)
 | |
|     - doc/site/step-by-step.md
 | |
|     - doc/site/how-to-*
 | |
|     - doc/site/faq.md (ledger compatibility)
 | |
|     - doc/site/installing.md
 | |
|     - doc/site/download.md
 | |
|     - doc/developer-guide.md
 | |
|     - doc/ANNOUNCE
 | |
| 
 | |
| - update version
 | |
|     - edit .version
 | |
|     - make setversion
 | |
|     - double-check & commit (cabal files, manual, download page..)
 | |
| 
 | |
| - make tarballs/binaries
 | |
|     - ensure no packages are commented out in Makefile's PACKAGES
 | |
|     - make cabalsdist
 | |
|     - [make windows binaries]
 | |
|     - [make mac binaries]
 | |
| 
 | |
| - release tests
 | |
|     - make haddocktest
 | |
|     - make cabalfiletest
 | |
|     - cabal tarballs install into a clean directory without warnings
 | |
|     - cabal upload --dry reports no problems
 | |
| 
 | |
| - tag
 | |
|     - make tagrelease
 | |
| 
 | |
| - publish
 | |
|     - stack upload hledger-lib; stack upload hledger; stack upload hledger-web
 | |
|       (or make cabalsdist hackageupload[-dry])
 | |
|     - [wait a day for it to appear in stackage nightly ?]
 | |
|     - ensure hackage is showing the latest haddocks
 | |
|     - check the hackage build matrix
 | |
|     - git push --tags
 | |
|     - deploy at demo.hledger.org
 | |
|     - [upload binaries to hledger.org]
 | |
|     - ensure the website is showing latest docs
 | |
|       (download links, release notes, manual, how-tos, dev guide links, etc.)
 | |
| 
 | |
| - announce
 | |
|     - review/close open issues in tracker
 | |
|     - email doc/ANNOUNCE to hledger, haskell-cafe, haskell, [ledger] lists
 | |
|     - tweet
 | |
|     - [blog]
 | |
|     - [reddit]
 | |
|     - update release notes with announcement link & short description
 | |
| 
 | |
| - post-release
 | |
|     - handle problem reports, support requests
 | |
| 
 | |
| 
 | |
| ### Do a minor release
 | |
| 
 | |
| Differences from a major release:
 | |
| work in a release branch,
 | |
| set PACKAGES only to the affected package(s),
 | |
| don't run make setversion.
 | |
| 
 | |
| 1. cleanup
 | |
|     - review working copies (laptop, server, website) & branches, commit pending changes
 | |
| 2. document
 | |
|     - */*.cabal for affected package(s) (descriptions, tested-with, files..)
 | |
|     - */CHANGES for affected package(s)
 | |
|     - doc/site/release-notes.md
 | |
|     - doc/manual.md (commands, options, --help, ledger compatibility..)
 | |
|     - doc/site/step-by-step.md
 | |
|     - doc/site/how-to-*
 | |
| 3. test
 | |
|     - make unittest
 | |
|     - make functest
 | |
|     - make haddocktest
 | |
| 4. branch
 | |
|     - switch to release branch (git checkout X.Y)
 | |
| 5. version
 | |
|     - edit .version (don't make setversion)
 | |
|     - manually bump version for affected package(s): cabal files, manual..
 | |
| 6. package
 | |
|     - set Makefile's PACKAGES to affected package(s)
 | |
|     - make cabalsdist
 | |
| 7. test
 | |
|     - install from tarball(s) into a clean directory
 | |
| 8. tag
 | |
|     - make tagrelease
 | |
| 9. push
 | |
|     - git push --tags
 | |
| 10. upload
 | |
|     - make cabalupload
 | |
| 11. announce
 | |
|     - [email hledger]
 | |
|     - [tweet]
 | |
| 
 | |
| 
 | |
| ## Project overview
 | |
| 
 | |
| ### Mission, principles, goals
 | |
| 
 | |
| The hledger project aims to produce:
 | |
| 
 | |
| - a practical, accessible, dependable tool for end users
 | |
| - a useful library and toolbox for finance-minded haskell programmers
 | |
| - a successful, time-and-money-solvent project within a thriving ecosystem of financial software projects.
 | |
| 
 | |
| ### Roles and activities
 | |
| 
 | |
| - newcomer/potential user
 | |
| - user
 | |
| - library user
 | |
| - field tester
 | |
| - bug wrangler
 | |
| - support
 | |
| - documentor
 | |
| - qa
 | |
| - developer
 | |
| - packager
 | |
| - communicator
 | |
| - project manager
 | |
| 
 | |
| ### Documentation
 | |
| 
 | |
| Project documentation lives in a number of places:
 | |
| 
 | |
| - `doc/*.md` and `doc/site/*.md` form the hledger.org website, which is generated with hakyll[-std] and pandoc
 | |
| - haddock documentation in the code appears on Hackage
 | |
| - short blurbs: cabal files, module headers, HCAR, GSOC project, ..
 | |
| - `doc/notes.org` has some old developer notes
 | |
| - developer reports (profiles, benchmarks, coverage..) in doc/profs, sometimes published at hledger.org/profs
 | |
| 
 | |
| ### Code
 | |
| 
 | |
| The hledger repo is hosted on Github, at <http://github.com/simonmichael/hledger>.
 | |
| You can also jump there via `code.hledger.org[/commits]`.
 | |
| 
 | |
| ### Quality control
 | |
| 
 | |
| Relevant tools include:
 | |
| 
 | |
| - unit tests (HUnit, make unittest)
 | |
| - functional tests (shelltestrunner, make functest)
 | |
| - performance tests (simplebench, make bench)
 | |
| - documentation tests (make haddocktest + manual)
 | |
| - ui tests (manual)
 | |
| - installation tests (manual)
 | |
| - code reviews
 | |
| 
 | |
| ### Code reviews
 | |
| 
 | |
| We have held one code review party, in July 2014, on the mail list and IRC channel.
 | |
| Here's the original [proposal](http://article.gmane.org/gmane.comp.finance.ledger.hledger/1070) giving some motivation, and the discussion logs, note these are a good source of hledger development tips:
 | |
| 
 | |
| - 2014/7/21-25 **hledger-web code & UI**
 | |
|   [mail thread](http://thread.gmane.org/gmane.comp.finance.ledger.hledger/1070),
 | |
|   [IRC log](http://hledger.org/static/irc-20140725-code-review.html)
 | |
| 
 | |
| 
 | |
| <!-- ### release process -->
 | |
| 
 | |
| <!-- ### roadmap -->
 | |
| 
 | |
| <!-- ### communication and collaboration -->
 | |
| 
 | |
| <!-- ### web presence and hosting setup -->
 | |
| 
 | |
| <!-- ### finances and other resources -->
 | |
| 
 | |
| <!-- ### licensing and legal issues -->
 | |
| 
 | |
| <!-- ### contributors and credits -->
 | |
| 
 | |
| 
 | |
| 
 | |
| ## Implementation notes
 | |
| 
 | |
| ### hledger
 | |
| 
 | |
| There are two core cabal packages:
 | |
| 
 | |
| **[hledger-lib](http://hackage.haskell.org/package/hledger-lib)** - data model, parsing, manipulation, standard reports
 | |
| ([github](https://github.com/simonmichael/hledger/tree/master/hledger-lib))\
 | |
| **[hledger](http://hackage.haskell.org/package/hledger)** - command line interface, reusable cli options & helpers
 | |
| ([github](https://github.com/simonmichael/hledger/tree/master/hledger))
 | |
| 
 | |
| Most data types are defined in hledger-lib:Hledger.Data.Types,
 | |
| while functions that operate on them are defined in
 | |
| hledger-lib:Hledger.Data.TYPENAME.
 | |
| Here's a diagram of the main data model:
 | |
| <img src="images/data-model.png">
 | |
| <!--
 | |
| generated by the old wiki from:
 | |
| <uml>
 | |
| hide empty members
 | |
| hide circle
 | |
| skinparam packageStyle Rect
 | |
| 
 | |
| Ledger *-- Journal
 | |
| Ledger *-- "*" Account
 | |
| note top of Ledger: A Journal and all its accounts with their balances.\nUsed for balance report
 | |
| note top of Journal: A journal file and parsed transactions & directives.\nUsed for print & register reports
 | |
| note bottom of Account: An account's name, balance (inclusive &\nexclusive), parent and child accounts
 | |
| Account o-- "*" Account :subaccounts, parent
 | |
| Journal o-- File
 | |
| File o-- "*" File :include
 | |
| Journal *-- "*" MarketPrice
 | |
| Journal *-- "*" Transaction
 | |
| MarketPrice -- Date
 | |
| MarketPrice -- Amount
 | |
| Transaction -- Date
 | |
| Transaction *-- "*" Posting
 | |
| Transaction o-- "*" Tag
 | |
| Posting o- "*" Tag
 | |
| Posting -- "0..1" Date
 | |
| Account -- AccountName
 | |
| Posting -- AccountName
 | |
| Account -- "2" MixedAmount
 | |
| Posting -- MixedAmount
 | |
| MixedAmount *-- "*" Amount
 | |
| Amount -- Commodity
 | |
| Amount -- Quantity
 | |
| Amount -- Price
 | |
| Amount -- AmountStyle
 | |
| </uml>
 | |
| -->
 | |
| 
 | |
| hledger parses the journal file into a
 | |
| [Journal](http://hackage.haskell.org/package/hledger-lib-0.23.2/docs/Hledger-Data-Types.html#t:Journal),
 | |
| which contains a list of
 | |
| [Transactions](http://hackage.haskell.org/package/hledger-lib-0.23.2/docs/Hledger-Data-Types.html#t:Transaction),
 | |
| each containing multiple
 | |
| [Postings](http://hackage.haskell.org/package/hledger-lib-0.23.2/docs/Hledger-Data-Types.html#t:Posting)
 | |
| of some
 | |
| [MixedAmount](http://hackage.haskell.org/package/hledger-lib-0.23.2/docs/Hledger-Data-Types.html#t:MixedAmount)
 | |
| (multiple
 | |
| single-[Commodity](http://hackage.haskell.org/package/hledger-lib-0.23.2/docs/Hledger-Data-Types.html#t:Commodity)
 | |
| [Amounts](http://hackage.haskell.org/package/hledger-lib-0.23.2/docs/Hledger-Data-Types.html#t:Amount))
 | |
| to some
 | |
| [AccountName](http://hackage.haskell.org/package/hledger-lib-0.23.2/docs/Hledger-Data-Types.html#t:AccountName).
 | |
| Commands get and render 
 | |
| [Reports](http://hackage.haskell.org/package/hledger-lib-0.23.2/docs/Hledger-Reports.html)
 | |
| from the Journal, or sometimes from a
 | |
| [Ledger](http://hackage.haskell.org/package/hledger-lib-0.23.2/docs/Hledger-Data-Types.html#t:Ledger),
 | |
| which contains
 | |
| [Accounts](http://hackage.haskell.org/package/hledger-lib-0.23.2/docs/Hledger-Data-Types.html#t:Account)
 | |
| representing the summed balances and other details of each account.
 | |
| 
 | |
| After surveying the packages, modules, and data types, try tracing the execution of a hledger command:
 | |
| 
 | |
| 1. CLI stuff is in [hledger:Hledger.Cli](https://github.com/simonmichael/hledger/tree/master/hledger/Hledger/Cli).
 | |
| 2. [hledger:Hledger.Cli.Main:main](https://github.com/simonmichael/hledger/blob/master/hledger/Hledger/Cli/Main.hs#L179)
 | |
| parses the command line to select a command, then
 | |
| 3. gives it to
 | |
| [hledger:Hledger.Cli.Utils:withJournalDo](https://github.com/simonmichael/hledger/blob/master/hledger/Hledger/Cli/Utils.hs#L61),
 | |
| which runs it after doing all the initial parsing.
 | |
| 4. Parsing code is under
 | |
| [hledger-lib:Hledger.Read](https://github.com/simonmichael/hledger/tree/master/hledger-lib/Hledger/Read.hs),
 | |
| eg the
 | |
| [hledger-lib:Hledger.Read.JournalReader](https://github.com/simonmichael/hledger/tree/master/hledger-lib/Hledger/Read/JournalReader.hs).
 | |
| 5. Commands extract useful information from the parsed data model using
 | |
| [hledger-lib:Hledger.Reports](https://github.com/simonmichael/hledger/tree/master/hledger-lib/Hledger/Reports),
 | |
| and
 | |
| 6. render it to the console.
 | |
| 7. Everything uses the types and data
 | |
| utilities under
 | |
| [hledger-lib:Hledger.Data](https://github.com/simonmichael/hledger/tree/master/hledger-lib/Hledger/Data),
 | |
| and the general helpers from
 | |
| [hledger-lib:Hledger.Utils](https://github.com/simonmichael/hledger/blob/master/hledger-lib/Hledger/Utils.hs)
 | |
| and below.
 | |
| 
 | |
| ### hledger-web
 | |
| 
 | |
| hledger-web is in a third cabal package:
 | |
| 
 | |
| **[hledger-web](http://hackage.haskell.org/package/hledger-web)** - web interface
 | |
| ([github](https://github.com/simonmichael/hledger/tree/master/hledger-web))
 | |
| 
 | |
| It is a single-executable web application using the
 | |
| [yesod](http://yesodweb.com) framework.  It runs a built-in web server
 | |
| serving some views of the journal file, reading it at startup and
 | |
| again whenever it changes. It can also append new transactions to the journal file.
 | |
| There are two main views, which can be filtered with [query arguments](manual#query-arguments):
 | |
| 
 | |
| - [/journal](http://demo.hledger.org/journal), showing general journal entries (like `hledger print`)
 | |
| 
 | |
| - [/register](http://demo.hledger.org/register?q=inacct:Assets:Bank:Checking),
 | |
|   showing transactions affecting an account (slightly different from
 | |
|   `hledger register`, which shows postings).
 | |
| 
 | |
| There is also:
 | |
| 
 | |
| - a sidebar (toggled by pressing `s`) showing the chart of accounts (like `hledger balance`)
 | |
| - an [add form](http://demo.hledger.org/journal?add=1) for adding new transactions (press `a`)
 | |
| - a help dialog showing quick help and keybindings (press `h` or click ?)
 | |
| 
 | |
| Most of the action is in
 | |
| 
 | |
| - [config/routes](https://github.com/simonmichael/hledger/tree/master/hledger-web/config/routes)
 | |
| - [templates/default-layout-wrapper.hamlet](https://github.com/simonmichael/hledger/tree/master/hledger-web/templates/default-layout-wrapper.hamlet)
 | |
| - [Foundation](https://github.com/simonmichael/hledger/tree/master/hledger-web/Foundation.hs)
 | |
| - [Handler.*](https://github.com/simonmichael/hledger/tree/master/hledger-web/Handler)
 | |
| - [static/hledger.js](https://github.com/simonmichael/hledger/tree/master/hledger-web/static/hledger.js)
 | |
| - [static/hledger.css](https://github.com/simonmichael/hledger/tree/master/hledger-web/static/hledger.css)
 | |
| 
 | |
| Handler module and function names end with R, like the Yesod-generated route type they deal with.
 | |
| 
 | |
| Dynamically generated page content is mostly inline hamlet.
 | |
| Lucius/Julius files and widgets generally are not used, except for the default layout.
 | |
| 
 | |
| The quickest way to test changes is `make ghciweb`, `:main --serve`, control-C, `:r`, repeat.
 | |
| No linking is required, and changes to static files like hledger.js are visible after reloading a page.
 | |
| 
 | |
| Another way is `yesod devel`, which rebuilds automatically when files
 | |
| change, including config files, templates and static files (but only in the hledger-web package).
 | |
| 
 | |
| A third way is `make autoweb`, if you can get it working (see the
 | |
| makefile for instructions). This rebuilds automatically when haskell
 | |
| files change in any of the hledger{-lib,,-web} packages.
 | |
| 
 |