Skip to content

Commit 039b710

Browse files
committed
Introduced --ledger-binary parameter
* If it is specified, but it's not there, an exception is thrown * If it's not specified, the defaults are probed * If it's not specified and the binary can't be found at either of the default locations, try launch `ledger` anyway, hoping it's in PATH * If everything fails, an informative exception is thrown
1 parent 3202e5c commit 039b710

File tree

1 file changed

+48
-23
lines changed

1 file changed

+48
-23
lines changed

icsv2ledger.py

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,11 @@ def get_locale_currency_symbol():
127127
os.path.join(os.path.expanduser('~'), '.icsv2ledgerrc-accounts')],
128128
'template_file': [
129129
os.path.join('.', '.icsv2ledgerrc-template'),
130-
os.path.join(os.path.expanduser('~'), '.icsv2ledgerrc-template')]})
130+
os.path.join(os.path.expanduser('~'), '.icsv2ledgerrc-template')],
131+
'ledger_binary_file': [
132+
'/usr/bin/ledger',
133+
'/usr/local/bin/ledger'
134+
]})
131135

132136
DEFAULT_TEMPLATE = """\
133137
{date} {cleared_character} {payee}
@@ -256,7 +260,12 @@ def parse_args_and_config_file():
256260
metavar='STR',
257261
help=('encoding of csv file'
258262
' (default: {0})'.format(DEFAULTS.encoding)))
259-
263+
parser.add_argument(
264+
'--ledger-binary',
265+
metavar='FILE',
266+
help=('path to ledger binary'
267+
' (default search order: {0})'
268+
.format(', '.join(FILE_DEFAULTS.ledger_binary_file))))
260269
parser.add_argument(
261270
'--ledger-file', '-l',
262271
metavar='FILE',
@@ -432,6 +441,17 @@ def parse_args_and_config_file():
432441
args.accounts_file, FILE_DEFAULTS.accounts_file)
433442
args.template_file = find_first_file(
434443
args.template_file, FILE_DEFAULTS.template_file)
444+
if args.ledger_binary is not None:
445+
# if ledger_binary was explicitly specified, check if it actually exists
446+
if find_first_file(args.ledger_binary, []) is None:
447+
# if not, throw an exception
448+
raise FileNotFoundError(
449+
'Can\'t find ledger binary at the specified location: {0}'.format(args.ledger_binary)
450+
)
451+
else:
452+
# otherwise try defaults
453+
args.ledger_binary = find_first_file(
454+
args.ledger_binary, FILE_DEFAULTS.ledger_binary_file)
435455

436456
if args.ledger_date_format and not args.csv_date_format:
437457
print('csv_date_format must be set'
@@ -645,30 +665,34 @@ def csv_md5sum_from_ledger(ledger_file):
645665
md5sum_hashes.add(m.group(1))
646666
return csv_comments, md5sum_hashes
647667

648-
def payees_from_ledger(ledger_file):
649-
return from_ledger(ledger_file, 'payees')
650668

669+
def payees_from_ledger(ledger_file, ledger_binary_file):
670+
return from_ledger(ledger_file, ledger_binary_file, 'payees')
651671

652-
def accounts_from_ledger(ledger_file):
653-
return from_ledger(ledger_file, 'accounts')
654672

673+
def accounts_from_ledger(ledger_file, ledger_binary_file):
674+
return from_ledger(ledger_file, ledger_binary_file, 'accounts')
655675

656-
def from_ledger(ledger_file, command):
657-
ledger = 'ledger'
658-
for f in ['/usr/bin/ledger', '/usr/local/bin/ledger']:
659-
if os.path.exists(f):
660-
ledger = f
661-
break
662676

677+
def from_ledger(ledger_file, ledger_binary_file, command):
678+
if ledger_binary_file is not None:
679+
# if either the --ledger-binary parameter was specified or a default ledger path was valid, use that
680+
ledger = ledger_binary_file
681+
else:
682+
# otherwise let's hope it's in PATH
683+
ledger = 'ledger'
663684
cmd = [ledger, "-f", ledger_file, command]
664-
p = subprocess.Popen(
665-
cmd,
666-
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
667-
(stdout_data, stderr_data) = p.communicate()
668-
items = set()
669-
for item in stdout_data.decode('utf-8').splitlines():
670-
items.add(item)
671-
return items
685+
try:
686+
p = subprocess.Popen(
687+
cmd,
688+
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
689+
(stdout_data, stderr_data) = p.communicate()
690+
items = set()
691+
for item in stdout_data.decode('utf-8').splitlines():
692+
items.add(item)
693+
return items
694+
except FileNotFoundError:
695+
raise FileNotFoundError('The system can\'t find the following ledger binary: {0}'.format(ledger))
672696

673697

674698
def read_mapping_file(map_file):
@@ -796,7 +820,7 @@ def main():
796820

797821
options = parse_args_and_config_file()
798822
# Define responses to yes/no prompts
799-
possible_yesno = set(['Y','N'])
823+
possible_yesno = set(['Y','N'])
800824

801825
# Get list of accounts and payees from Ledger specified file
802826
possible_accounts = set([])
@@ -805,8 +829,8 @@ def main():
805829
md5sum_hashes = set()
806830
csv_comments = set()
807831
if options.ledger_file:
808-
possible_accounts = accounts_from_ledger(options.ledger_file)
809-
possible_payees = payees_from_ledger(options.ledger_file)
832+
possible_accounts = accounts_from_ledger(options.ledger_file, options.ledger_binary)
833+
possible_payees = payees_from_ledger(options.ledger_file, options.ledger_binary)
810834
csv_comments, md5sum_hashes = csv_md5sum_from_ledger(options.ledger_file)
811835

812836
# Read mappings
@@ -978,6 +1002,7 @@ def process_csv_lines(csv_lines):
9781002
print()
9791003
sys.exit(0)
9801004

1005+
9811006
if __name__ == "__main__":
9821007
main()
9831008

0 commit comments

Comments
 (0)