command line accounting tool for Linux and macOS
yaml
files as data storecsv
files to yaml
formatCODE_OF_CONDUCT.md
for fundamental guidelinescargo install rust_ledger
We distribute binaries for the above platforms. See releases for a complete list by version.
Alternatively, clone this repo and do the following:
cargo build --release
to compile the binary/target/release
and copy the rust_ledger
binary in your path: /usr/bin
rust_ledger --help
will provide a menu of all available commands and optional arguments.
```bash
rust_ledger
USAGE: rust_ledger [SUBCOMMAND]
FLAGS: -h, --help Prints help information -V, --version Prints version information
SUBCOMMANDS: account account module balance balance module budget budget module csv csv module help Prints this message or the help of the given subcommand(s) register register module ```
rust_ledger COMMAND -f LEDGER_FILE_PATH
LEDGERFILEPATH (denoted by -f
) - relative path to location of yaml ledger file
RLEDGER_FILE
in lieu of specifying whenever
the program is invoked.-f
is provided with a file path the file provided will be used instead of any RLEDGER_FILE
set.
RLEDGER_FILE=~/rledger.yaml rust_ledger balance
RLEDGER_FILE
can be set as a system or user environment variable.
export RLEDGER_FILE=$HOME/rledger.yaml
RLEDGER_FILE
- Path to rledger file. ex: RLEDGER_FILE=~/rledger.yaml
NO_COLOR
- Disables color output. ex: NO_COLOR=true
yaml
file formatIn lieu of the plain text ledger file format, this project uses a defined YAML schema. YAML has a relatively clean
syntax and is able to represent useful data types (lists, etc) natively. Further, parsing yaml
via is easy thanks to
tools such as serde
. These facts allowed me to skip writing a custom parser to support the "ledger" plain text file
format and focus on implementing functionality.
yaml
file can be found at examples/example.yaml
yaml
files in the following format:```yaml accounts: - account: amount:
transactions: - date: amount: description: account: offset_account: - date: description: transactions: - amount: account: - amount: account: ```
The ledger format schema is purposely lightweight. The only requirements are as follows:
account
field should be expressed in the following format: account_classification:account_name
.amount
field should be a number. It can include up to two (2) decimal points.date
field should be in the following format: YYYY-MM-DD
.Transactions can be expressed in two different ways. One is a "simplified" format for transactions that only impact two accounts:
yaml
- date: 2020-01-01
amount: 200
offset_account: liability:cc_amex
description: grocery store
account: expense:expense_general
The sign (debit / credit) associated with the offset_account
value is the opposite of the sign of the value contained
in amount
field.
In the above example transaction, since expense_general
was debited by 200, the cc_amex
account will be credited by
the same amount.
Transactions that involve more than two accounts are expressed in the following manner:
yaml
- date: 2020-01-01
description: grocery store
transactions:
- amount: 20
account: expense:general
- amount: 180
account: expense:grocery
- amount: -200
account: liability:cc_amex
Transactions that only involve two accounts can also be expressed in the above format.
cargo test
```bash rust_ledger-account account module
USAGE:
rust_ledger account [OPTIONS] --filename
FLAGS: -h, --help Prints help information -V, --version Prints version information
OPTIONS:
-f, --filename
example output:
```
asset:cashchecking asset:cashsavings liability:cc_amex equity:equity expense:grocery expense:general expense:mortgage income:general ```
```bash rust_ledger-balance balance module
USAGE:
rust_ledger balance [OPTIONS] --filename
FLAGS: -h, --help Prints help information -V, --version Prints version information
OPTIONS:
-f, --filename
example output:
Account | Balance
---------------------+------------
asset |
asset:cash_checking | $-400.00
asset:cash_savings | $1,000.00
liability |
liability:cc_amex | $-455.00
equity |
equity:equity | $-3,500.00
expense |
expense:grocery | $635.00
expense:general | $1,020.00
expense:mortgage | $2,000.00
income |
income:general | $-300.00
|
check | 0
```bash rust_ledger-register register module
USAGE:
rust_ledger register [OPTIONS] --filename
FLAGS: -h, --help Prints help information -V, --version Prints version information
OPTIONS:
-f, --filename
example output:
Date | Description | Account | Amount
------------+--------------------+---------------------+------------
2019-12-31 | weekly groceries | expense:grocery | $455.00
2019-12-31 | weekly groceries | liability:cc_amex | $-455.00
2020-01-01 | mortage | expense:mortgage | $2,000.00
2020-01-01 | mortage | asset:cash_checking | $-2,000.00
2020-01-01 | stuff | expense:general | $1,000.00
2020-01-01 | stuff | asset:cash_savings | $-1,000.00
2020-01-01 | grocery store | expense:general | $20.00
2020-01-01 | grocery store | expense:grocery | $180.00
2020-01-01 | grocery store | asset:cash_checking | $-200.00
2020-01-01 | donut sale to dale | asset:cash_checking | $300.00
2020-01-01 | donut sale to dale | income:general | $-300.00
```bash rust_ledger-budget budget module
USAGE:
rust_ledger budget [OPTIONS] --filename
FLAGS: -h, --help Prints help information -V, --version Prints version information
OPTIONS:
-f, --filename
group
parameter (year
or month
)option
parameter. For example, this value could be 2020
if using a year group
parameter or 12
(December) if using a month
group parameter.example output:
Date | Budget | Actual | Delta
------------------+------------+-----------+------------
expense:grocery | $6,000.00 | $180.00 | $5,820.00
expense:mortgage | $24,000.00 | $2,000.00 | $22,000.00
expense:general | 0 | $1,020.00 | $-1,020.00
income:general | 0 | $-300.00 | $300.00
```bash rust_ledger-csv csv module
USAGE:
rust_ledger csv [OPTIONS] --csv
FLAGS: -h, --help Prints help information -i, --invert invert amount for each csv transaction -V, --version Prints version information
OPTIONS:
-c, --csv
csv
files to yaml
format expected by rust_ledger
.-f
and -c
arguments. These include the rust_ledger file location (unless specified via
environment variable), csv file location and account offset, respectively.-i
flag can be used to invert the sign of the "amount" column values that are being imported. This is useful
when working with CSV files that represent debits as negative values and credits as positive values.-o
argument) would be the offset transaction that the csv transactions should be posted against.description
fields and will populate the
appropriate expense/income accounts for any matches. Non-matches will use a default of expense:general
or income:general
, which is determined based on the sign of the amount
field (or debit
or credit
) contained in
the transaction.The CSV tool can import columns with the following case-sensitive names:
Often, banks will provide exports in one of two formats: 1) amounts are represented in one column whereby debits and credits are identified by negative and positive (or vice-versa) amounts or 2) separate debit and credit columns. The CSV import tool can handle both scenarios.
CSV file(s) should have date
, description
and name
columns as they are required fields.