Config

NAME

App::Moneymoor::Config - the data home, the budget file list, and the four global display settings.

SYNOPSIS


use App::Moneymoor::Config;

my $cfg = App::Moneymoor::Config.new;
$cfg.load;                          # reads ~/.moneymoor/config.json

say $cfg.available-budget-names;    # ('household', 'business')

$cfg.budget-name = 'household';
say $cfg.budget-path;               # /Users/you/.moneymoor/household.db

$cfg.theme        = 'nord';
$cfg.icons        = 'nerd';
$cfg.currency     = '€';
$cfg.decimal-mark = ',';
$cfg.save;                          # back to ~/.moneymoor/config.json

DESCRIPTION

Moneymoor keeps everything under one directory:

~/.moneymoor/
      config.json          # this file: last-used budget, theme,
                           #            icons, currency, decimal mark
      household.db         # a sqlcipher budget
      business.db          # another one
      logs/error.log       # Selkie's stderr redirect while the TUI runs

Budgets are flat files in the data home, not per-profile subdirectories: a budget is a single sqlcipher database with no sidecar state, so a directory per budget would be a directory containing exactly one file. The login screen lists ~/.moneymoor/*.db and the basename is the budget name.

Everything is derived from moneymoor-home, which honours the MONEYMOOR_HOME environment variable. That override exists for the test suite — a test that wrote to the real ~/.moneymoor could clobber a user's budget list — but it is equally useful for keeping a throwaway budget out of the normal picker.

What is not here

Nothing about a budget's contents. Category order, hidden flags, collapsed groups and the viewed period all live in the encrypted database or in the Selkie store, because they are per-budget facts and this file is deliberately plaintext (it has to be readable before a passphrase exists — the login screen is themed from the first frame).

ATTRIBUTES

  • budget-name — the last budget opened, pre-selected by the login screen next launch. Defaults to 'budget'.

  • theme — palette name, resolved through App::Moneymoor::Themes::load. Defaults to 'gruvbox'.

  • icons — glyph tier, 'unicode' (default) or 'nerd'. Resolved through App::Moneymoor::Service::Icons::icons, which maps an unknown tier back onto unicode, so a hand-edited config cannot break rendering.

  • currency — the symbol money is rendered with: 'Ā£' (default), '$' or '€'. Display only — App::Moneymoor::Util::Money converts nothing and the engine has never heard of a currency.

  • decimal-mark — '.' (default) or ',', stored under the JSON key decimal_mark. Thousands are grouped with the other one, so this single setting moves both characters, in both directions: '1,234.56' or '1.234,56' on the way out, and the matching shape accepted on the way in.

currency and decimal-mark are the two settings this class validates, because they are the two that are handed to a routine that refuses an unknown value (set-money-locale throws). A value outside the whitelist — a hand-edited "currency": "CAD" — falls back to the default silently, the same treatment Service::Icons gives an unknown glyph tier: the plaintext config is user-editable by design, and the failure mode for a typo in it must be "the app opens in Ā£" rather than "the app does not open".

METHODS

  • moneymoor-home — ~/.moneymoor, or $MONEYMOOR_HOME.

  • budget-path — derived ~/.moneymoor/{budget-name}.db.

  • budget-path-for($name) — the same derivation for any name, for the login screen's "open the one the user just picked".

  • budget-exists — is there a file at budget-path?

  • available-budget-names — every *.db basename in the data home, most-recently-modified first, so the picker opens on the budget the user was last in.

  • valid-budget-name($name) — the create-a-budget name rule: letters, digits, ., _, -. Rejects anything that could escape the data home.

  • error-log-path — ~/.moneymoor/logs/error.log, handed to Selkie::App so warnings don't splatter over the TUI.

  • ensure-directories — create the data home if missing.

  • load($path?) / save / config-path — JSON round-trip.

EXAMPLES

Pointing a test at a scratch home


my $scratch = $*TMPDIR.add("moneymoor-test-{$*PID}").Str;
%*ENV<MONEYMOOR_HOME> = $scratch;

my $cfg = App::Moneymoor::Config.new.load;
$cfg.icons = 'nerd';
$cfg.save;

App::Moneymoor::Config.new.load.icons;      # 'nerd'

Opening whatever the user picked in the login Select


my $path = $cfg.budget-path-for($login.selected-budget);
my $db   = App::Moneymoor::DB.new(db-path => $path);
my $res  = $db.connect($passphrase);
if $res ~~ Failure {
    $login.set-status($res.exception.message, :error);
    $res.so;                       # a handled Failure must be defused
}

SEE ALSO

App::Moneymoor v0.4.2

YNAB-style envelope budgeting: a derivation engine

Authors

  • Matt Doughty

License

Artistic-2.0

Dependencies

DBIish:ver<0.6.7>:auth<zef:raku-community-modules>Notcurses::Native:ver<0.6.5+>:auth<zef:apogee>Selkie:ver<0.16.0+>:auth<zef:apogee>JSON::Fast:ver<0.19>:auth<cpan:TIMOTIMO>MacOS::NativeLib:ver<0.0.6>:auth<zef:lizmat>

Test Dependencies

Provides

  • App::Moneymoor
  • App::Moneymoor::Config
  • App::Moneymoor::DB
  • App::Moneymoor::Gateway::Account
  • App::Moneymoor::Gateway::Assignment
  • App::Moneymoor::Gateway::Category
  • App::Moneymoor::Gateway::Payee
  • App::Moneymoor::Gateway::Transaction
  • App::Moneymoor::Handlers::Boot
  • App::Moneymoor::Model::Account
  • App::Moneymoor::Model::Assignment
  • App::Moneymoor::Model::Category
  • App::Moneymoor::Model::CategoryGroup
  • App::Moneymoor::Model::Payee
  • App::Moneymoor::Model::Split
  • App::Moneymoor::Model::Transaction
  • App::Moneymoor::Screen::Accounts
  • App::Moneymoor::Screen::Budget
  • App::Moneymoor::Screen::Login
  • App::Moneymoor::Screen::Main
  • App::Moneymoor::Screen::Main::Keybinds
  • App::Moneymoor::Screen::Main::Modals
  • App::Moneymoor::Screen::Main::Subscriptions
  • App::Moneymoor::Screen::Reports
  • App::Moneymoor::Service::Budget
  • App::Moneymoor::Service::Icons
  • App::Moneymoor::Service::Target
  • App::Moneymoor::Service::Workspace
  • App::Moneymoor::StoreHandlers
  • App::Moneymoor::Theme
  • App::Moneymoor::Theme::Catppuccin
  • App::Moneymoor::Theme::Dracula
  • App::Moneymoor::Theme::Everforest
  • App::Moneymoor::Theme::Gruvbox
  • App::Moneymoor::Theme::Kanagawa
  • App::Moneymoor::Theme::Monokai
  • App::Moneymoor::Theme::Nord
  • App::Moneymoor::Theme::OneDark
  • App::Moneymoor::Theme::RosePine
  • App::Moneymoor::Theme::Solarized
  • App::Moneymoor::Theme::TokyoNight
  • App::Moneymoor::Themes
  • App::Moneymoor::UI
  • App::Moneymoor::Util::Money
  • App::Moneymoor::Util::Period
  • App::Moneymoor::View::BudgetRow
  • App::Moneymoor::View::EmptyState
  • App::Moneymoor::View::HintBar
  • App::Moneymoor::View::InspectorPane
  • App::Moneymoor::View::ModalChrome
  • App::Moneymoor::View::RegisterRow
  • App::Moneymoor::View::ReportRow
  • App::Moneymoor::Widget::BannerBar
  • App::Moneymoor::Widget::BootProgressModal

The Camelia image is copyright 2009 by Larry Wall. "Raku" is a trademark of the Yet Another Society. All rights reserved.

Built with Podlite — the markup and publishing tools behind this site.