* 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 | |-------------------------|----------------------------------------------------------------------------| | 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), @LedgerTips | | hledger-web demo   | [demo.hledger.org](http://demo.hledger.org) | | Trello | [backlog/wishlist planning board](http://hledger.org/trello) | | Github | [code.hledger.org](http://github.com/simonmichael/hledger) (simonmichael/hledger)
[![build status (travis)](https://travis-ci.org/simonmichael/hledger.svg?branch=master) (travis)](https://travis-ci.org/simonmichael/hledger), [build status (hydra)](http://hydra.cryp.to/jobset/hledger/master#tabs-jobs)
[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)
[open bugs](https://github.com/simonmichael/hledger/issues?direction=desc&labels=BUG&page=1&sort=created&state=open), [all bugs](https://github.com/simonmichael/hledger/issues?direction=desc&labels=BUG&page=1&sort=created), [open issues](https://github.com/simonmichael/hledger/issues?direction=desc&labels=&page=1&sort=created&state=open), [all issues](https://github.com/simonmichael/hledger/issues?direction=desc&labels=&page=1&sort=created), issues with bounties, issue bounties @ bountysource.com | | 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)
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)
outdated dependencies: [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)
reverse dependencies: [hledger-lib](http://packdeps.haskellers.com/reverse/hledger-lib), [hledger](http://packdeps.haskellers.com/reverse/hledger)
[download stats (BestHaskell)](http://best-haskell.herokuapp.com/#/category/Finance) | | 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)
[build status (jenkins)](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
[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)
binary packages
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)
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)
all: [\*hledger\*](https://packages.debian.org/search?searchon=names&keywords=hledger)
popularity stats: [hledger](https://qa.debian.org/popcon.php?package=haskell-hledger), [hledger-web](https://qa.debian.org/popcon.php?package=haskell-hledger-web)
[PTS help](https://www.debian.org/doc/manuals/developers-reference/resources.html#pkg-tracking-system) | | Ubuntu | source packages
[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)
binary packages
[\*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) | ## 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)) ### 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 ``` ### 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 . 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) ## 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: 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.