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 throughApp::Moneymoor::Themes::load. Defaults to'gruvbox'.iconsā glyph tier,'unicode'(default) or'nerd'. Resolved throughApp::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 keydecimal_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 atbudget-path?available-budget-namesā every*.dbbasename 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 toSelkie::Appso 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::Screen::Login ā the consumer of
available-budget-namesandbudget-path-for.App::Moneymoor::Themes ā resolves
theme.App::Moneymoor::Service::Icons ā resolves
icons.App::Moneymoor::Util::Money ā owns the whitelists
currencyanddecimal-markare checked against, and is pointed at them byApp::Moneymoor::UIat startup.