hledger/doc/developer-guide.md
2014-11-04 20:33:26 -08:00

21 KiB

Developer guide

^ hledger.org: ^ release notes, download ^ ^ Github: ^ code, commits, COMMITS (turn up your volume) \ commits only in master, commits only in release branch \ build status (hydra) \ open bugs, all bugs, open issues, all issues ^ ^ Hackage: ^ hledger-lib, hledger, hledger-web, hledger-interest, hledger-irr, hledger-vty, hledger-chart, hledger \ reverse dependencies: hledger-lib, hledger, outdated dependencies \ download activity ^ ^ Stackage: ^ hledger entry, issues \ build status (jenkins), last build output: 7.4, 7.6, 7.8 ^ ^ Debian: ^ source packages \ haskell-hledger-lib, bugs, haskell-hledger, bugs, haskell-hledger-web, bugs \ binary packages \ testing: hledger, bugs, hledger-web, bugs \ unstable: hledger, bugs, hledger-web, bugs \ all: hledger \ popularity stats: hledger, hledger-web \ PTS help ^ ^ Ubuntu: ^ source packages \ haskell-hledger-lib, bugs, haskell-hledger, bugs, haskell-hledger-web, bugs \ binary packages \ hledger ^ ^ Gentoo: ^ hledger, hledger-web, hledger ^ ^ Fedora: ^ hledger, hledger ^


Project overview

A rough overview/blueprint for the hledger project.

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 appears in many places:

  • website
  • user manual
  • developer guide
  • code documentation: haddock
  • various developer reports
  • developer notes outline
  • blurbs: in cabal files, module headers, google project, repo message of the day..

For most of hledger's history, documentation was primarily (all capitals) markdown files in the source code repository. This was processed by pandoc, hakyll or yst to generate a static website.

As of 2014/2, hledger.org is a wiki, and most docs are maintained as wiki pages. Some, particularly the user manual and release notes, still exist in the main source repo as well. These should probably not be updated directly, instead they are copied from the wiki before each release.

Code

The hledger repo is hosted on github.com: http://github.com/simonmichael/hledger. (You can also jump there via hledger.org/code[/commits], or 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 held a code review party, hopefully the first of many, in July 2014 on the mail list and IRC channel. Here's the original proposal giving some motivation, and the discussion logs, note these are a good source of hledger development tips:


Implementation notes

hledger

There are two core cabal packages:

hledger-lib - data model, parsing, manipulation, standard reports (github)\ hledger - command line interface, reusable cli options & helpers (github)

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:

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 -- "" HistoricalPrice Journal -- "" Transaction HistoricalPrice -- Date HistoricalPrice -- 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

hledger parses the journal file into a Journal, which contains a list of Transactions, each containing multiple Postings of some MixedAmount (multiple single-Commodity Amounts) to some AccountName. Commands get and render Reports from the Journal, or sometimes from a Ledger, which contains Accounts 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.
  2. hledger:Hledger.Cli.Main:main parses the command line to select a command, then
  3. gives it to hledger:Hledger.Cli.Utils:withJournalDo, which runs it after doing all the initial parsing.
  4. Parsing code is under hledger-lib:Hledger.Read, eg the hledger-lib:Hledger.Read.JournalReader.
  5. Commands extract useful information from the parsed data model using hledger-lib:Hledger.Reports, and
  6. render it to the console.
  7. Everything uses the types and data utilities under hledger-lib:Hledger.Data, and the general helpers from hledger-lib:Hledger.Utils and below.

hledger-web

hledger-web is in a third cabal package:

hledger-web - web interface (github)

It is a single-executable web application using the yesod 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 manual#query-arguments:

  • /journal, showing general journal entries (like hledger print)

  • /register, 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 for adding new transactions (press a)
  • a help dialog showing quick help and keybindings (press h or click ?)

Most of the action is in

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.


How to..

New contributors of all levels are most welcome. Here are some tips to help you get productive on the hledger project.

Suggest enhancements

Suggestions and feature requests are easy to make. They are welcome feedback, but we don't want them to pile up and obscure bugs and other developer priorities, so we try manage them a. with discussion and b. optionally as cards on a trello board. The current recommendation is

  1. discuss/research first\ Is your wish already on the trello wishlist/planning board or bug tracker ?\ In any case, perhaps discuss it on irc or the mail list first ?

  2. wishes are best stored on trello\ Is it a problem with the current released product ? report in the bug tracker\ Is it a feature idea or wish ? add a card on the trello board, if needed

But do what you think best. When a wish does land in the bug tracker, it gets the WISH label.

Report problems

  • check for related issues in the bug tracker or in the mail list archive
  • discuss/confirm the issue on irc or list
  • report new issues in the bug tracker

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
  • discuss/report problems via irc/mail list/bug tracker

Help with bug tracking

Set up for development

  1. get an up-to-date ghc, at least 7.0 and preferably 7.6

  2. there's probably no need to install the haskell platform now, but you could

  3. it's probably worth getting the latest and best cabal: cabal update; cabal install cabal-install

  4. ensure you have git installed

  5. the hledger Makefile assumes GNU Make, so on some platforms you may need to spell "make" as "gmake"

  6. get the hledger repo:

     git clone git@github.com:simonmichael/hledger.git
     cd hledger
    
  7. install packages required to build hledger and add-ons, or as many of them as possible:

     cabal update
     make install
    

    This will also try to cabal install development builds of the hledger executables, so ghc-pkg unregister those afterwards if you don't want that.

  8. try building with make:

     make bin/hledgerdev
    

    This is usually quicker and simpler than fiddling with multiple cabal packages during development. Note this executable will not be as optimised as the normal cabal build, and has the "dev" suffix as a reminder of this.

  9. try auto-building with sp:

     make auto   # or autoweb
    

    You'll need to follow the instructions to install sp. This is how I do most hledger development. It will recompile whenever you save changes to source files.

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 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: ")

Run the tests

  • set up for hledger development
  • cabal install shelltestrunner
  • make test

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

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
  • 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