diff --git a/features/core.feature b/features/core.feature index 4418d1b9..b8a987ec 100644 --- a/features/core.feature +++ b/features/core.feature @@ -180,7 +180,7 @@ Feature: Basic reading and writing to a journal And the journal should contain "Life is good." But the journal should not contain "I have an @idea" And the journal should not contain "I met with" - When we run "jrnl --import -i features/journals/tags.journal" + When we run "jrnl --import --file features/journals/tags.journal" Then the journal should contain "My first entry." And the journal should contain "Life is good." And the journal should contain "PROFIT!" @@ -191,10 +191,11 @@ Feature: Basic reading and writing to a journal And the journal should contain "Life is good." But the journal should not contain "I have an @idea" And the journal should not contain "I met with" - When we run "jrnl --import -i features/journals/tags.journal" and pipe + When we run "jrnl --import --file features/journals/tags.journal" and pipe """ [2020-07-05 15:00] I should not exist! """ Then the journal should contain "My first entry." And the journal should contain "PROFIT!" But the journal should not contain "I should not exist!" + diff --git a/jrnl/EncryptedJournal.py b/jrnl/EncryptedJournal.py index ec4ceee8..5f553603 100644 --- a/jrnl/EncryptedJournal.py +++ b/jrnl/EncryptedJournal.py @@ -47,6 +47,7 @@ class EncryptedJournal(Journal): print(f"[Directory {dirname} created]", file=sys.stderr) self.create_file(filename) self.password = util.create_password(self.name) + print( f"Encrypted journal '{self.name}' created at {filename}", file=sys.stderr, @@ -90,11 +91,16 @@ class EncryptedJournal(Journal): @classmethod def from_journal(cls, other: Journal): new_journal = super().from_journal(other) - new_journal.password = ( - other.password - if hasattr(other, "password") - else util.create_password(other.name) - ) + try: + new_journal.password = ( + other.password + if hasattr(other, "password") + else util.create_password(other.name) + ) + except KeyboardInterrupt: + print("[Interrupted while creating new journal]", file=sys.stderr) + sys.exit(1) + return new_journal diff --git a/jrnl/cli.py b/jrnl/cli.py index 2b15ccba..f2cbbc3e 100644 --- a/jrnl/cli.py +++ b/jrnl/cli.py @@ -24,75 +24,15 @@ import packaging.version import platform import sys -from . import install, plugins, util +from . import install, util +from . import jrnl from .parse_args import parse_args -from .Journal import PlainJournal, open_journal -from .util import ERROR_COLOR, RESET_COLOR, UserAbort +from .Journal import open_journal +from .util import UserAbort from .util import get_journal_name +from .util import WARNING_COLOR, RESET_COLOR log = logging.getLogger(__name__) -logging.getLogger("keyring.backend").setLevel(logging.ERROR) - - -def guess_mode(args, config): - """Guesses the mode (compose, read or export) from the given arguments""" - compose = True - export = False - if ( - args.decrypt is not False - or args.encrypt is not False - or args.export is not False - or any((args.short, args.tags, args.edit, args.delete)) - ): - compose = False - export = True - elif any( - ( - args.start_date, - args.end_date, - args.on_date, - args.limit, - args.strict, - args.starred, - args.contains, - ) - ): - # Any sign of displaying stuff? - compose = False - elif args.text and all( - word[0] in config["tagsymbols"] for word in " ".join(args.text).split() - ): - # No date and only tags? - compose = False - - return compose, export - - -def encrypt(journal, filename=None): - """ Encrypt into new file. If filename is not set, we encrypt the journal file itself. """ - from .EncryptedJournal import EncryptedJournal - - journal.config["encrypt"] = True - - new_journal = EncryptedJournal.from_journal(journal) - new_journal.write(filename) - - print( - "Journal encrypted to {}.".format(filename or new_journal.config["journal"]), - file=sys.stderr, - ) - - -def decrypt(journal, filename=None): - """ Decrypts into new file. If filename is not set, we encrypt the journal file itself. """ - journal.config["encrypt"] = False - - new_journal = PlainJournal.from_journal(journal) - new_journal.write(filename) - print( - "Journal decrypted to {}.".format(filename or new_journal.config["journal"]), - file=sys.stderr, - ) def update_config(config, new_config, scope, force_local=False): @@ -113,9 +53,8 @@ def configure_logger(debug=False): level=logging.DEBUG if debug else logging.ERROR, format="%(levelname)-8s %(name)-12s %(message)s", ) - logging.getLogger("parsedatetime").setLevel( - logging.INFO - ) # disable parsedatetime debug logging + logging.getLogger("parsedatetime").setLevel(logging.INFO) + logging.getLogger("keyring.backend").setLevel(logging.ERROR) def run(manual_args=None): @@ -132,18 +71,29 @@ Please update to Python 3.7 (or higher) in order to use jrnl. ) sys.exit(1) + """ + Flow: + 1. Parse cli arguments + 2. Run standalone command if it doesn't require config (help, version, etc), then exit + 3. Load config + 4. Run standalone command if it does require config (encrypt, decrypt, etc), then exit + 5. Load specified journal + 6. Start write mode, or search mode + 7. Profit + """ if manual_args is None: manual_args = sys.argv[1:] args = parse_args(manual_args) configure_logger(args.debug) + log.debug("Parsed args: %s", args) # Run command if possible before config is available if callable(args.preconfig_cmd): args.preconfig_cmd(args) sys.exit(0) - # Load the config + # Load the config, and extract journal name try: config = install.load_or_install_jrnl() original_config = config.copy() @@ -155,7 +105,7 @@ Please update to Python 3.7 (or higher) in order to use jrnl. # Run post-config command now that config is ready if callable(args.postconfig_cmd): - args.postconfig_cmd(args=args, config=config) + args.postconfig_cmd(args=args, config=config, original_config=original_config) sys.exit(0) # --- All the standalone commands are now done --- # @@ -163,144 +113,15 @@ Please update to Python 3.7 (or higher) in order to use jrnl. # Get the journal we're going to be working with journal = open_journal(args.journal_name, config) - mode_compose, mode_export = guess_mode(args, config) + kwargs = { + "args": args, + "config": config, + "journal": journal, + } - if mode_compose and not args.text: - if not sys.stdin.isatty(): - # Piping data into jrnl - raw = sys.stdin.read() - elif config["editor"]: - template = "" - if config["template"]: - try: - template = open(config["template"]).read() - except OSError: - print( - f"[Could not read template at '{config['template']}']", - file=sys.stderr, - ) - sys.exit(1) - raw = util.get_text_from_editor(config, template) - else: - try: - _how_to_quit = ( - "Ctrl+z and then Enter" if "win32" in sys.platform else "Ctrl+d" - ) - print( - f"[Writing Entry; on a blank line, press {_how_to_quit} to finish writing]\n", - file=sys.stderr, - ) - raw = sys.stdin.read() - except KeyboardInterrupt: - print("[Entry NOT saved to journal]", file=sys.stderr) - sys.exit(0) - if raw: - args.text = [raw] - else: - sys.exit() + if jrnl._is_write_mode(**kwargs): + jrnl.write_mode(**kwargs) + else: + jrnl.search_mode(**kwargs) - # Writing mode - if mode_compose: - raw = " ".join(args.text).strip() - log.debug('Appending raw line "%s" to journal "%s"', raw, args.journal_name) - journal.new_entry(raw) - print(f"[Entry added to {args.journal_name} journal]", file=sys.stderr) - journal.write() - - if not mode_compose: - old_entries = journal.entries - if args.on_date: - args.start_date = args.end_date = args.on_date - journal.filter( - tags=args.text, - start_date=args.start_date, - end_date=args.end_date, - strict=args.strict, - starred=args.starred, - exclude=args.excluded, - contains=args.contains, - ) - journal.limit(args.limit) - - # Reading mode - if not mode_compose and not mode_export: - print(journal.pprint()) - - # Various export modes - elif args.short: - print(journal.pprint(short=True)) - - elif args.tags: - print(plugins.get_exporter("tags").export(journal)) - - elif args.export is not False: - exporter = plugins.get_exporter(args.export) - print(exporter.export(journal, args.output)) - - elif args.encrypt is not False: - encrypt(journal, filename=args.encrypt) - # Not encrypting to a separate file: update config! - if not args.encrypt: - update_config( - original_config, {"encrypt": True}, args.journal_name, force_local=True - ) - install.save_config(original_config) - - elif args.decrypt is not False: - decrypt(journal, filename=args.decrypt) - # Not decrypting to a separate file: update config! - if not args.decrypt: - update_config( - original_config, {"encrypt": False}, args.journal_name, force_local=True - ) - install.save_config(original_config) - - elif args.edit: - if not config["editor"]: - print( - "[{1}ERROR{2}: You need to specify an editor in {0} to use the --edit function.]".format( - install.CONFIG_FILE_PATH, ERROR_COLOR, RESET_COLOR - ), - file=sys.stderr, - ) - sys.exit(1) - other_entries = [e for e in old_entries if e not in journal.entries] - # Edit - old_num_entries = len(journal) - edited = util.get_text_from_editor(config, journal.editable_str()) - journal.parse_editable_str(edited) - num_deleted = old_num_entries - len(journal) - num_edited = len([e for e in journal.entries if e.modified]) - prompts = [] - if num_deleted: - prompts.append( - "{} {} deleted".format( - num_deleted, "entry" if num_deleted == 1 else "entries" - ) - ) - if num_edited: - prompts.append( - "{} {} modified".format( - num_edited, "entry" if num_deleted == 1 else "entries" - ) - ) - if prompts: - print("[{}]".format(", ".join(prompts).capitalize()), file=sys.stderr) - journal.entries += other_entries - journal.sort() - journal.write() - - elif args.delete: - if journal.entries: - entries_to_delete = journal.prompt_delete_entries() - - if entries_to_delete: - journal.entries = old_entries - journal.delete_entries(entries_to_delete) - - journal.write() - else: - print( - "No entries deleted, because the search returned no results.", - file=sys.stderr, - ) + # All done! diff --git a/jrnl/commands.py b/jrnl/commands.py index 8461d64a..544dd1dc 100644 --- a/jrnl/commands.py +++ b/jrnl/commands.py @@ -1,19 +1,35 @@ +""" +Functions in this file are standalone commands. All standalone commands are split into +two categories depending on whether they require the config to be loaded to be able to +run. + +1. "preconfig" commands don't require the config at all, and can be run before the + config has been loaded. +2. "postconfig" commands require to config to have already been loaded, parsed, and + scoped before they can be run. + +Also, please note that all (non-builtin) imports should be scoped to each function to +avoid any possible overhead for these standalone commands. +""" +import platform +import sys + + def preconfig_diagnostic(_): - import platform - import sys - import jrnl + from jrnl import __version__ print( - f"jrnl: {jrnl.__version__}\n" + f"jrnl: {__version__}\n" f"Python: {sys.version}\n" f"OS: {platform.system()} {platform.release()}" ) def preconfig_version(_): - import jrnl + from jrnl import __title__ + from jrnl import __version__ - version_str = f"{jrnl.__title__} version {jrnl.__version__}" + version_str = f"{__title__} version {__version__}" print(version_str) @@ -31,4 +47,59 @@ def postconfig_import(args, config, **kwargs): journal = open_journal(args.journal_name, config) format = args.export if args.export else "jrnl" - get_importer(format).import_(journal, args.input) + get_importer(format).import_(journal, args.filename) + + +def postconfig_encrypt(args, config, original_config, **kwargs): + """ + Encrypt a journal in place, or optionally to a new file + """ + from .EncryptedJournal import EncryptedJournal + from .Journal import open_journal + from .cli import update_config + from .install import save_config + + # Open the journal + journal = open_journal(args.journal_name, config) + + journal.config["encrypt"] = True + + new_journal = EncryptedJournal.from_journal(journal) + new_journal.write(args.filename) + + print( + f"Journal encrypted to {args.filename or new_journal.config['journal']}.", + file=sys.stderr, + ) + + # Update the config, if we encrypted in place + if not args.filename: + update_config( + original_config, {"encrypt": True}, args.journal_name, force_local=True + ) + save_config(original_config) + + +def postconfig_decrypt(args, config, original_config, **kwargs): + """ Decrypts into new file. If filename is not set, we encrypt the journal file itself. """ + from .Journal import PlainJournal + from .Journal import open_journal + from .cli import update_config + from .install import save_config + + journal = open_journal(args.journal_name, config) + journal.config["encrypt"] = False + + new_journal = PlainJournal.from_journal(journal) + new_journal.write(args.filename) + print( + f"Journal decrypted to {args.filename or new_journal.config['journal']}.", + file=sys.stderr, + ) + + # Update the config, if we decrypted in place + if not args.filename: + update_config( + original_config, {"encrypt": False}, args.journal_name, force_local=True + ) + save_config(original_config) diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py new file mode 100644 index 00000000..c7a80368 --- /dev/null +++ b/jrnl/jrnl.py @@ -0,0 +1,266 @@ +import logging +import sys + +from . import util +from . import install +from . import plugins + +from .util import ERROR_COLOR +from .util import RESET_COLOR + +log = logging.getLogger(__name__) + + +def _is_write_mode(args, config, **kwargs): + """Determines if we are in write mode (as opposed to search mode)""" + write_mode = True + + # Are any search filters present? If so, then search mode. + write_mode = not any( + ( + args.contains, + args.delete, + args.edit, + args.export, + args.end_date, + args.limit, + args.on_date, + args.short, + args.starred, + args.start_date, + args.strict, + args.tags, + ) + ) + + # If the text is entirely tags, then we are also searching (not writing) + if ( + write_mode + and args.text + and all(word[0] in config["tagsymbols"] for word in " ".join(args.text).split()) + ): + write_mode = False + + return write_mode + + +def write_mode(args, config, journal, **kwargs): + """ + Gets input from the user to write to the journal + 1. Check for input from cli + 2. Check input being piped in + 3. Open editor if configured (prepopulated with template if available) + 4. Use stdin.read as last resort + 6. Write any found text to journal, or exit + """ + log.debug("Write mode: starting") + + if args.text: + log.debug("Write mode: cli text detected: %s", args.text) + raw = " ".join(args.text).strip() + + elif not sys.stdin.isatty(): + log.debug("Write mode: receiving piped text") + raw = sys.stdin.read() + + else: + raw = _write_in_editor(config) + + if not raw: + log.error("Write mode: couldn't get raw text") + sys.exit() + + log.debug( + 'Write mode: appending raw text to journal "%s": %s', args.journal_name, raw + ) + journal.new_entry(raw) + print(f"[Entry added to {args.journal_name} journal]", file=sys.stderr) + journal.write() + log.debug("Write mode: completed journal.write()", args.journal_name, raw) + + +def search_mode(args, journal, **kwargs): + """ + Search for entries in a journal, then either: + 1. Send them to configured editor for user manipulation + 2. Delete them (with confirmation for each entry) + 3. Display them (with formatting options) + """ + kwargs = { + **kwargs, + "args": args, + "journal": journal, + "old_entries": journal.entries, + } + + # Filters the journal entries in place + _search_journal(**kwargs) + + # Where do the search results go? + if args.edit: + _edit_search_results(**kwargs) + + elif args.delete: + _delete_search_results(**kwargs) + + else: + _display_search_results(**kwargs) + + +def _write_in_editor(config): + if config["editor"]: + log.debug("Write mode: opening editor") + template = _get_editor_template(config) + raw = util.get_text_from_editor(config, template) + + else: + _how_to_quit = "Ctrl+z and then Enter" if "win32" in sys.platform else "Ctrl+d" + print( + f"[Writing Entry; on a blank line, press {_how_to_quit} to finish writing]\n", + file=sys.stderr, + ) + try: + raw = sys.stdin.read() + except KeyboardInterrupt: + log.error("Write mode: keyboard interrupt") + print("[Entry NOT saved to journal]", file=sys.stderr) + sys.exit(0) + + return raw + + +def _get_editor_template(config, **kwargs): + log.debug("Write mode: loading template for entry") + + if not config["template"]: + log.debug("Write mode: no template configured") + return "" + + try: + template = open(config["template"]).read() + log.debug("Write mode: template loaded: %s", template) + except OSError: + log.error("Write mode: template not loaded") + print( + f"[Could not read template at '{config['template']}']", file=sys.stderr, + ) + sys.exit(1) + + return template + + +def _search_journal(args, journal, **kwargs): + """ Search the journal with the given args""" + if args.on_date: + args.start_date = args.end_date = args.on_date + + journal.filter( + tags=args.text, + start_date=args.start_date, + end_date=args.end_date, + strict=args.strict, + starred=args.starred, + exclude=args.excluded, + contains=args.contains, + ) + journal.limit(args.limit) + + +def _edit_search_results(config, journal, old_entries, **kwargs): + """ + 1. Send the given journal entries to the user-configured editor + 2. Print out stats on any modifications to journal + 3. Write modifications to journal + """ + if not config["editor"]: + print( + f""" + [{ERROR_COLOR}ERROR{RESET_COLOR}: There is no editor configured.] + + Please specify an editor in config file ({install.CONFIG_FILE_PATH}) + to use the --edit option. + """, + file=sys.stderr, + ) + sys.exit(1) + + # separate entries we are not editing + other_entries = [e for e in old_entries if e not in journal.entries] + + # Get stats now for summary later + old_stats = _get_predit_stats(journal) + + # Send user to the editor + edited = util.get_text_from_editor(config, journal.editable_str()) + journal.parse_editable_str(edited) + + # Print summary if available + _print_edited_summary(journal, old_stats) + + # Put back entries we separated earlier, sort, and write the journal + journal.entries += other_entries + journal.sort() + journal.write() + + +def _print_edited_summary(journal, old_stats, **kwargs): + stats = { + "deleted": old_stats["count"] - len(journal), + "modified": len([e for e in journal.entries if e.modified]), + } + + prompts = [] + + if stats["deleted"]: + prompts.append( + f"{stats['deleted']} {_pluralize_entry(stats['deleted'])} deleted" + ) + + if stats["modified"]: + prompts.append( + f"{stats['modified']} {_pluralize_entry(stats['modified'])} modified" + ) + + if prompts: + print(f"[{', '.join(prompts).capitalize()}]", file=sys.stderr) + + +def _get_predit_stats(journal): + return {"count": len(journal)} + + +def _pluralize_entry(num): + return "entry" if num == 1 else "entries" + + +def _delete_search_results(journal, old_entries, **kwargs): + if not journal.entries: + print( + "[No entries deleted, because the search returned no results.]", + file=sys.stderr, + ) + sys.exit(1) + + entries_to_delete = journal.prompt_delete_entries() + + if entries_to_delete: + journal.entries = old_entries + journal.delete_entries(entries_to_delete) + + journal.write() + + +def _display_search_results(args, journal, **kwargs): + if args.short: + print(journal.pprint(short=True)) + + elif args.tags: + print(plugins.get_exporter("tags").export(journal)) + + elif args.export: + exporter = plugins.get_exporter(args.export) + print(exporter.export(journal, args.filename)) + + else: + # Default display mode + print(journal.pprint()) diff --git a/jrnl/parse_args.py b/jrnl/parse_args.py index 46df31c3..8623a603 100644 --- a/jrnl/parse_args.py +++ b/jrnl/parse_args.py @@ -9,13 +9,18 @@ from .commands import preconfig_version from .commands import preconfig_diagnostic from .commands import postconfig_list from .commands import postconfig_import +from .commands import postconfig_encrypt +from .commands import postconfig_decrypt from .util import deprecated_cmd -class WrappingFormatter(argparse.RawDescriptionHelpFormatter): +class WrappingFormatter(argparse.RawTextHelpFormatter): def _split_lines(self, text, width): - text = self._whitespace_matcher.sub(" ", text).strip() - return textwrap.wrap(text, width=56) + text = text.split("\n\n") + text = map(lambda t: self._whitespace_matcher.sub(" ", t).strip(), text) + text = map(lambda t: textwrap.wrap(t, width=56), text) + text = [item for sublist in text for item in sublist] + return text def parse_args(args=[]): @@ -54,7 +59,7 @@ def parse_args(args=[]): action="store_const", const=preconfig_version, dest="preconfig_cmd", - help="prints version information", + help="Print version information", ) standalone.add_argument( "-v", @@ -75,7 +80,7 @@ def parse_args(args=[]): action="store_const", const=postconfig_list, dest="postconfig_cmd", - help="list all configured journals", + help="List all configured journals", ) standalone.add_argument( "--ls", @@ -95,21 +100,19 @@ def parse_args(args=[]): ) standalone.add_argument( "--encrypt", - metavar="FILENAME", - dest="encrypt", - help="Encrypts your existing journal with a new password", - nargs="?", - default=False, - const=None, + help="Encrypt selected journal with a password", + action="store_const", + metavar="TYPE", + dest="postconfig_cmd", + const=postconfig_encrypt, ) standalone.add_argument( "--decrypt", - metavar="FILENAME", - dest="decrypt", - help="Decrypts your journal and stores it in plain text", - nargs="?", - default=False, - const=None, + help="Decrypt selected journal and store it in plain text", + action="store_const", + metavar="TYPE", + dest="postconfig_cmd", + const=postconfig_decrypt, ) standalone.add_argument( "--import", @@ -117,18 +120,27 @@ def parse_args(args=[]): metavar="TYPE", dest="postconfig_cmd", const=postconfig_import, - help=f"Import entries into your journal. TYPE can be: {util.oxford_list(IMPORT_FORMATS)} (default: jrnl)", + help=f""" + Import entries from another journal. + + Optional parameters: + + --file FILENAME (default: uses stdin) + + --format [{util.oxford_list(IMPORT_FORMATS)}] (default: jrnl) + """, ) standalone.add_argument( - "-i", + "--file", metavar="FILENAME", - dest="input", - help="Optionally specifies input file when using --import.", - default=False, - const=None, + dest="filename", + help=argparse.SUPPRESS, + default=None, ) + standalone.add_argument("-i", dest="filename", help=argparse.SUPPRESS) - compose_msg = """ To add a new entry into your journal, simply write it on the command line: + compose_msg = """ + To add a new entry into your journal, simply write it on the command line: jrnl yesterday: I was walking and I found this big log. @@ -171,9 +183,7 @@ def parse_args(args=[]): metavar="DATE", help="Show entries before, or on, this date (alias: -until)", ) - reading.add_argument( - "-until", dest="end_date", help=argparse.SUPPRESS, - ) + reading.add_argument("-until", dest="end_date", help=argparse.SUPPRESS) reading.add_argument( "-contains", dest="contains", @@ -214,7 +224,7 @@ def parse_args(args=[]): search_options_msg = """ These help you do various tasks with the selected entries from your search. If used on their own (with no search), they will act on your entire journal""" exporting = parser.add_argument_group( - "Options for Searching", textwrap.dedent(search_options_msg) + "Searching Options", textwrap.dedent(search_options_msg) ) exporting.add_argument( "--edit", @@ -233,7 +243,15 @@ def parse_args(args=[]): metavar="TYPE", dest="export", choices=EXPORT_FORMATS, - help=f"Display selected entries in an alternate format (other than jrnl). TYPE can be: {util.oxford_list(EXPORT_FORMATS)}.", + help=f""" + Display selected entries in an alternate format. + + TYPE can be: {util.oxford_list(EXPORT_FORMATS)}. + + Optional parameters: + + --file FILENAME Write output to file instead of stdout + """, default=False, ) exporting.add_argument( @@ -259,17 +277,11 @@ def parse_args(args=[]): "-s", dest="short", action="store_true", help=argparse.SUPPRESS, ) exporting.add_argument( - "-o", - metavar="FILENAME", - dest="output", - help="Optionally specifies output file (or directory) when using --format.", - default=False, - const=None, + "-o", dest="filename", help=argparse.SUPPRESS, ) # Handle '-123' as a shortcut for '-n 123' num = re.compile(r"^-(\d+)$") args = [num.sub(r"-n \1", arg) for arg in args] - # return parser.parse_args(args) return parser.parse_intermixed_args(args) diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index dbec5a6b..2920322a 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -14,17 +14,14 @@ def expected_args(**kwargs): default_args = { "contains": None, "debug": False, - "decrypt": False, "delete": False, "edit": False, - "encrypt": False, "end_date": None, "excluded": [], "export": False, - "input": False, + "filename": None, "limit": None, "on_date": None, - "output": False, "preconfig_cmd": None, "postconfig_cmd": None, "short": False, @@ -66,7 +63,15 @@ def test_edit_alone(): def test_encrypt_alone(): - assert cli_as_dict("--encrypt 'test.txt'") == expected_args(encrypt="test.txt") + from jrnl.commands import postconfig_encrypt + + assert cli_as_dict("--encrypt") == expected_args(postconfig_cmd=postconfig_encrypt) + + +def test_decrypt_alone(): + from jrnl.commands import postconfig_decrypt + + assert cli_as_dict("--decrypt") == expected_args(postconfig_cmd=postconfig_decrypt) def test_end_date_alone(): @@ -110,15 +115,10 @@ def test_import_alone(): assert cli_as_dict("--import") == expected_args(postconfig_cmd=postconfig_import) -def test_input_flag_alone(): - assert cli_as_dict("-i test.txt") == expected_args(input="test.txt") - assert cli_as_dict("-i 'lorem ipsum.txt'") == expected_args(input="lorem ipsum.txt") - - -def test_output_flag_alone(): - assert cli_as_dict("-o test.txt") == expected_args(output="test.txt") - assert cli_as_dict("-o 'lorem ipsum.txt'") == expected_args( - output="lorem ipsum.txt" +def test_file_flag_alone(): + assert cli_as_dict("--file test.txt") == expected_args(filename="test.txt") + assert cli_as_dict("--file 'lorem ipsum.txt'") == expected_args( + filename="lorem ipsum.txt" )