git-subtree-dir: doc/haskellerz git-subtree-mainline:684af10643git-subtree-split:79beb34b90
		
			
				
	
	
		
			364 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			364 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<?xml version="1.0" encoding="utf-8"?>
 | 
						||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 | 
						||
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 | 
						||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
						||
<head>
 | 
						||
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 | 
						||
  <meta http-equiv="Content-Style-Type" content="text/css" />
 | 
						||
  <meta name="generator" content="pandoc" />
 | 
						||
  <meta name="author" content="Simon Michael" />
 | 
						||
  <meta name="date" content="2021-04-29" />
 | 
						||
  <title>Inside hledger: an architectural tour and how-to</title>
 | 
						||
  <style type="text/css">
 | 
						||
    code{white-space: pre-wrap;}
 | 
						||
    span.smallcaps{font-variant: small-caps;}
 | 
						||
    span.underline{text-decoration: underline;}
 | 
						||
    div.column{display: inline-block; vertical-align: top; width: 50%;}
 | 
						||
    div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
 | 
						||
    ul.task-list{list-style: none;}
 | 
						||
    .display.math{display: block; text-align: center; margin: 0.5rem auto;}
 | 
						||
  </style>
 | 
						||
  <link rel="stylesheet" type="text/css" media="screen, projection, print"
 | 
						||
    href="https://www.w3.org/Talks/Tools/Slidy2/styles/slidy.css" />
 | 
						||
  <script src="https://www.w3.org/Talks/Tools/Slidy2/scripts/slidy.js"
 | 
						||
    charset="utf-8" type="text/javascript"></script>
 | 
						||
</head>
 | 
						||
<body>
 | 
						||
<div class="slide titlepage">
 | 
						||
  <h1 class="title">Inside hledger: an architectural tour and how-to</h1>
 | 
						||
  <p class="author">
 | 
						||
Simon Michael
 | 
						||
  </p>
 | 
						||
  <p class="date">April 29, 2021</p>
 | 
						||
</div>
 | 
						||
<div id="introductions" class="title-slide slide section level1">
 | 
						||
<h1>Introductions</h1>
 | 
						||
<p><code>0:00 (10m)</code></p>
 | 
						||
</div>
 | 
						||
<div id="who-am-i" class="slide section level2">
 | 
						||
<h1>Who am I ?</h1>
 | 
						||
<p>Simon Michael<br />
 | 
						||
Independent software consultant and developer.<br />
 | 
						||
<!-- Currently based in Hawaii. --> <a href="https://joyful.com" class="uri">https://joyful.com</a></p>
 | 
						||
<p>Started in the home computer era (Ireland, 80s). ZX-80, Pet, VIC, C64, Amiga, PC, Mac, VAX/VMS, unix..</p>
 | 
						||
<p>FOSS fan, contributor, project leader. Two big projects:</p>
 | 
						||
<ul>
 | 
						||
<li><p><strong>Zwiki</strong>, 1996-2006, wiki engine, Python/Zope</p></li>
 | 
						||
<li><p><strong>hledger</strong>, 2006-present, accounting tool, Haskell</p></li>
 | 
						||
</ul>
 | 
						||
</div>
 | 
						||
<div id="overview-of-talk" class="slide section level2">
 | 
						||
<h1>Overview of talk</h1>
 | 
						||
<ul>
 | 
						||
<li><p>A quick intro to plain text accounting and hledger. (10m)</p></li>
 | 
						||
<li><p>A tour of hledger’s architecture, codebase, evolutions, and design principles. (25m)</p></li>
 | 
						||
<li><p>How to script and develop hledger: custom commands, calling from other apps, troubleshooting, bug investigation, effective pull requests. (25m)</p></li>
 | 
						||
<li><p>Q&A to go deeper on whatever you like. (30m)</p></li>
 | 
						||
</ul>
 | 
						||
</div>
 | 
						||
<div id="whats-plain-text-accounting" class="slide section level2">
 | 
						||
<h1>What’s Plain Text Accounting ?</h1>
 | 
						||
<p>A name I proposed (and a website I built) to help unify and grow the communities around Ledger, hledger, Beancount and similar accounting tools.</p>
 | 
						||
<p><a href="https://plaintextaccounting.org" class="uri">https://plaintextaccounting.org</a></p>
 | 
						||
</div>
 | 
						||
<div id="the-pta-ecosystem" class="slide section level2">
 | 
						||
<h1>The PTA ecosystem</h1>
 | 
						||
<p>The “big three” apps:</p>
 | 
						||
<ul>
 | 
						||
<li><p><strong>Ledger</strong> - John Wiegley’s pioneering command line accounting app, inspiration for all the rest.<br />
 | 
						||
C++, 2003-present</p></li>
 | 
						||
<li><p><strong>hledger</strong> - Simon Michael’s rewrite/remix.<br />
 | 
						||
Haskell, 2007-present</p></li>
 | 
						||
<li><p><strong>Beancount</strong> - Martin Blais’ variant.<br />
 | 
						||
Python, 2008-present</p></li>
 | 
						||
</ul>
 | 
						||
<p>Many more apps and add-on tools - <a href="https://plaintextaccounting.org/#software" class="uri">https://plaintextaccounting.org/#software</a></p>
 | 
						||
</div>
 | 
						||
<div id="whats-hledger" class="slide section level2">
 | 
						||
<h1>What’s hledger ?</h1>
 | 
						||
<p>A suite of tools, file formats, and documentation for doing “plain text accounting”.</p>
 | 
						||
<p><a href="https://hledger.org" class="uri">https://hledger.org</a></p>
 | 
						||
</div>
 | 
						||
<div id="hledger-project-goals" class="slide section level2">
 | 
						||
<h1>hledger project goals</h1>
 | 
						||
<p>I was a Ledger user and new Haskeller. I started hledger with many goals:</p>
 | 
						||
<ul>
 | 
						||
<li>acquire a more robust, usable, evolving incarnation of Ledger</li>
 | 
						||
<li>develop a consistent, effective accounting habit</li>
 | 
						||
<li>get better at Haskell</li>
 | 
						||
<li>find out if Haskell was good for end-user apps and maintainer productivity</li>
 | 
						||
<li>grow a useful, long-lasting, financially sustainable FOSS accounting project</li>
 | 
						||
</ul>
 | 
						||
</div>
 | 
						||
<div id="an-end-user-haskell-application" class="slide section level2">
 | 
						||
<h1>An end-user Haskell application</h1>
 | 
						||
<p>hledger is something that’s not yet common:</p>
 | 
						||
<p>An end user application (ie: not a programming tool), written in Haskell, that aims to be</p>
 | 
						||
<ul>
 | 
						||
<li>easy to install,</li>
 | 
						||
<li>dependable,</li>
 | 
						||
<li>and pleasing to use,</li>
 | 
						||
<li>on all major platforms,</li>
 | 
						||
<li>by non-techies as well as power users.</li>
 | 
						||
</ul>
 | 
						||
</div>
 | 
						||
<div id="a-successful-foss-project" class="slide section level2">
 | 
						||
<h1>A successful FOSS project</h1>
 | 
						||
<p>15 years, 134 contributors, 80-100 chatters, some number of happy users, useful to me every week.</p>
 | 
						||
<p>Reasonably successful.</p>
 | 
						||
<p>Not fulfilling my original goal of being financially self-sustaining and minimally time-consuming !</p>
 | 
						||
</div>
 | 
						||
<div id="tools" class="slide section level2">
 | 
						||
<h1>Tools</h1>
 | 
						||
<ul>
 | 
						||
<li>hledger</li>
 | 
						||
<li>hledger-ui</li>
 | 
						||
<li>hledger-web</li>
 | 
						||
<li>hledger-iadd</li>
 | 
						||
<li>hledger-interest</li>
 | 
						||
<li>etc.</li>
 | 
						||
</ul>
 | 
						||
</div>
 | 
						||
<div id="file-formats" class="slide section level2">
 | 
						||
<h1>File formats</h1>
 | 
						||
<ul>
 | 
						||
<li>journal</li>
 | 
						||
<li>csv</li>
 | 
						||
<li>timeclock</li>
 | 
						||
<li>timedot</li>
 | 
						||
</ul>
 | 
						||
</div>
 | 
						||
<div id="documentation" class="slide section level2">
 | 
						||
<h1>Documentation</h1>
 | 
						||
<ul>
 | 
						||
<li>introductory</li>
 | 
						||
<li>reference</li>
 | 
						||
<li>cookbook</li>
 | 
						||
<li>developer</li>
 | 
						||
</ul>
 | 
						||
</div>
 | 
						||
 | 
						||
<div id="architecture" class="title-slide slide section level1">
 | 
						||
<h1>Architecture</h1>
 | 
						||
<p><code>0:10 (25m)</code></p>
 | 
						||
</div>
 | 
						||
<div id="a-fast-run-through-the-evolution" class="slide section level2">
 | 
						||
<h1>A fast run through the evolution</h1>
 | 
						||
<ul>
 | 
						||
<li>First commit</li>
 | 
						||
<li>First types</li>
 | 
						||
<li>First report</li>
 | 
						||
<li>Balance report</li>
 | 
						||
<li>Multi-column balance report</li>
 | 
						||
<li>Stateful parser</li>
 | 
						||
<li>Web interface</li>
 | 
						||
<li>Curses interface</li>
 | 
						||
<li>Package split</li>
 | 
						||
<li>Speed, features</li>
 | 
						||
<li>General currency conversion</li>
 | 
						||
<li>Valuation</li>
 | 
						||
<li>Always documentation</li>
 | 
						||
</ul>
 | 
						||
</div>
 | 
						||
<div id="a-tour-of-the-codebase-and-project-today-2021q2" class="slide section level2">
 | 
						||
<h1>A tour of the codebase and project today (2021Q2)</h1>
 | 
						||
</div>
 | 
						||
<div id="design-principles" class="slide section level2">
 | 
						||
<h1>Design principles</h1>
 | 
						||
</div>
 | 
						||
 | 
						||
<div id="how-to.." class="title-slide slide section level1">
 | 
						||
<h1>How to..</h1>
 | 
						||
<p><code>0:35 (25m)</code></p>
 | 
						||
</div>
 | 
						||
<div id="script-hledger" class="slide section level2">
 | 
						||
<h1>Script hledger</h1>
 | 
						||
<ul>
 | 
						||
<li><a href="https://hledger.org/scripting.html" class="uri">https://hledger.org/scripting.html</a></li>
 | 
						||
</ul>
 | 
						||
</div>
 | 
						||
<div id="integrate-hledger-in-your-app" class="slide section level2">
 | 
						||
<h1>Integrate hledger in your app</h1>
 | 
						||
<ul>
 | 
						||
<li><p>Run cli, capture csv/json</p></li>
 | 
						||
<li><p>Run hledger-web, use http-json api</p></li>
 | 
						||
<li><p>Link with hledger-lib and/or other hledger packages, call public functions</p></li>
 | 
						||
</ul>
 | 
						||
</div>
 | 
						||
<div id="investigate-a-hledger-bug" class="slide section level2">
 | 
						||
<h1>Investigate a hledger bug</h1>
 | 
						||
<ul>
 | 
						||
<li><p>Basic troubleshooting - docs, comparison, minimisation, reproduction, support</p></li>
 | 
						||
<li><p>Code debugging</p></li>
 | 
						||
</ul>
 | 
						||
</div>
 | 
						||
<div id="how-to-submit-a-pull-request" class="slide section level2">
 | 
						||
<h1>How to submit a pull request</h1>
 | 
						||
<ul>
 | 
						||
<li><a href="https://hledger.org/CONTRIBUTING.html#pull-requests" class="uri">https://hledger.org/CONTRIBUTING.html#pull-requests</a></li>
 | 
						||
</ul>
 | 
						||
</div>
 | 
						||
 | 
						||
<div id="q-a" class="title-slide slide section level1">
 | 
						||
<h1>Q & A</h1>
 | 
						||
<p><code>1:00 (30m)</code></p>
 | 
						||
</div>
 | 
						||
 | 
						||
<div id="end" class="title-slide slide section level1">
 | 
						||
<h1>End</h1>
 | 
						||
<p><code>1:30</code></p>
 | 
						||
<pre><code>$ git shortlog -s
 | 
						||
Aerex
 | 
						||
Aiken Cairncross
 | 
						||
Alejandro García Montoro
 | 
						||
Aleksandar Dimitrov
 | 
						||
Alex Chen
 | 
						||
Alvaro Fernando García
 | 
						||
Amarandus
 | 
						||
Amitai Burstein
 | 
						||
Andreas Pauley
 | 
						||
Andrew Jones
 | 
						||
Andriy Mykhaylyk
 | 
						||
Arnout Engelen
 | 
						||
Ben Boeckel
 | 
						||
Ben Creasy
 | 
						||
Boyd Kelly
 | 
						||
Brian Scott
 | 
						||
Brian Wignall
 | 
						||
Bryan Richter
 | 
						||
Caleb Maclennan
 | 
						||
Carel Fellinger
 | 
						||
Carl Richard Theodor Schneider
 | 
						||
Carlos Lopez-Camey
 | 
						||
Christian G. Warden
 | 
						||
Christoph Nicolai
 | 
						||
Clint Adams
 | 
						||
Colin Woodbury
 | 
						||
Damien Cassou
 | 
						||
David Reaver
 | 
						||
David Zhang
 | 
						||
Dmitry Astapov
 | 
						||
Dominik Süß
 | 
						||
Doug Goldstein
 | 
						||
Eli Flanagan
 | 
						||
Elijah Caine
 | 
						||
Eric Kow
 | 
						||
Eric Mertens
 | 
						||
Everett Hildenbrandt
 | 
						||
Evilham
 | 
						||
Felix Van der Jeugt
 | 
						||
Felix Yan
 | 
						||
Fun Ilrys (Nissar Chababy)
 | 
						||
Gabriel Ebner
 | 
						||
Gaith Hallak
 | 
						||
Gergely Risko
 | 
						||
Hans-Peter Deifel
 | 
						||
Henning Thielemann
 | 
						||
Imuli
 | 
						||
Jacek Generowicz
 | 
						||
Jacob Weisz
 | 
						||
Jakob Schöttl
 | 
						||
Jakub Zárybnický
 | 
						||
Jan Zerebecki
 | 
						||
Jeff Richards
 | 
						||
Jesse Rosenthal
 | 
						||
Joachim Breitner
 | 
						||
Joe Horsnell
 | 
						||
Johann Klähn
 | 
						||
Johannes Gerer
 | 
						||
John Wiegley
 | 
						||
Joseph Weston
 | 
						||
Joshua Chia
 | 
						||
Joshua Kehn
 | 
						||
Judah Jacobson
 | 
						||
Julien Moutinho
 | 
						||
Justin Le
 | 
						||
Kyle Marek-Spartz
 | 
						||
Luca Molteni
 | 
						||
Léo Gaspard
 | 
						||
M Parker
 | 
						||
Malte Brandy
 | 
						||
Mark Hansen
 | 
						||
Marko Kocić
 | 
						||
Martin Michlmayr
 | 
						||
Mateus Furquim
 | 
						||
Matthias Kauer
 | 
						||
Max Bolingbroke
 | 
						||
Michael Kainer
 | 
						||
Michael Sanders
 | 
						||
Michael Snoyman
 | 
						||
Michael Walker
 | 
						||
Mick Dekkers
 | 
						||
Mitchell Rosen
 | 
						||
Moritz Kiefer
 | 
						||
Mykola Orliuk
 | 
						||
Nadrieril
 | 
						||
Nicholas Niro
 | 
						||
Nick Ingolia
 | 
						||
Nicolas Wavrant
 | 
						||
Nikhil Jha
 | 
						||
Nissar Chababy
 | 
						||
Nolan Darilek
 | 
						||
Oliver Braun
 | 
						||
Omari Norman
 | 
						||
Pavan Rikhi
 | 
						||
Pavlo Kerestey
 | 
						||
Peter Simons
 | 
						||
Pia Mancini
 | 
						||
Rick Lupton
 | 
						||
Roman Cheplyaka
 | 
						||
Rui Chen
 | 
						||
Ryan Desfosses
 | 
						||
Sam Doshi
 | 
						||
Sam Jeeves
 | 
						||
Samuel May
 | 
						||
Sergei Trofimovich
 | 
						||
Sergey Astanin
 | 
						||
Shubham Lagwankar
 | 
						||
Simon Hengel
 | 
						||
Simon Michael
 | 
						||
SpicyCat
 | 
						||
Stefano Rodighiero
 | 
						||
Stephen Morgan
 | 
						||
Steven R. Baker
 | 
						||
TANIGUCHI Kohei
 | 
						||
Thomas R. Koll
 | 
						||
Tim Docker
 | 
						||
Timofey ZAKREVSKIY
 | 
						||
Trygve Laugstøl
 | 
						||
Vladimir Sorokin
 | 
						||
Vladimir Zhelezov
 | 
						||
Wad
 | 
						||
Xinruo Sun
 | 
						||
afarrow
 | 
						||
agander
 | 
						||
aragaer
 | 
						||
awjchen
 | 
						||
azure-pipelines[bot]
 | 
						||
flip111
 | 
						||
gwern
 | 
						||
jeevcat
 | 
						||
jungle-boogie
 | 
						||
legrostdg
 | 
						||
trevorriles
 | 
						||
zieone</code></pre>
 | 
						||
<!-- 
 | 
						||
https://pandoc.org/MANUAL.html#slide-shows
 | 
						||
 | 
						||
By default, the slide level is the highest heading level in the
 | 
						||
hierarchy that is followed immediately by content, and not another
 | 
						||
heading, somewhere in the document. In the example above, level-1
 | 
						||
headings are always followed by level-2 headings, which are followed
 | 
						||
by content, so the slide level is 2. This default can be overridden
 | 
						||
using the --slide-level option.
 | 
						||
 | 
						||
The document is carved up into slides according to the following rules:
 | 
						||
A horizontal rule always starts a new slide.
 | 
						||
A heading at the slide level always starts a new slide.
 | 
						||
Headings below the slide level in the hierarchy create headings within a slide.
 | 
						||
Headings above the slide level in the hierarchy create “title slides,” which just contain the section title and help to break the slide show into sections. Non-slide content under these headings will be included on the title slide (for HTML slide shows) or in a subsequent slide with the same title (for beamer).
 | 
						||
-->
 | 
						||
</div>
 | 
						||
</body>
 | 
						||
</html>
 |