mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-05-17 19:48:31 +02:00
Merge branch 'develop' into change-time-docs
This commit is contained in:
commit
1cd34167bd
14 changed files with 90 additions and 22 deletions
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -9,6 +9,17 @@
|
||||||
- Reformat additional messages and finish centralizing exception handling [\#1424](https://github.com/jrnl-org/jrnl/pull/1424) ([wren](https://github.com/wren))
|
- Reformat additional messages and finish centralizing exception handling [\#1424](https://github.com/jrnl-org/jrnl/pull/1424) ([wren](https://github.com/wren))
|
||||||
- Reformat messages and add new centralized exception handling [\#1417](https://github.com/jrnl-org/jrnl/pull/1417) ([wren](https://github.com/wren))
|
- Reformat messages and add new centralized exception handling [\#1417](https://github.com/jrnl-org/jrnl/pull/1417) ([wren](https://github.com/wren))
|
||||||
|
|
||||||
|
**Fixed bugs:**
|
||||||
|
|
||||||
|
- Empty config file leads to confusing error message [\#1420](https://github.com/jrnl-org/jrnl/issues/1420)
|
||||||
|
- "Entry not saved" text doesn't appear in default stdin editor [\#1419](https://github.com/jrnl-org/jrnl/issues/1419)
|
||||||
|
- '-not -contains x' raises an AttributeError exception [\#1350](https://github.com/jrnl-org/jrnl/issues/1350)
|
||||||
|
- Directory YAML export shows stack trace when it doesn't need to [\#1227](https://github.com/jrnl-org/jrnl/issues/1227)
|
||||||
|
- The `-not` option with no arguments now outputs error instead of stack trace [\#1466](https://github.com/jrnl-org/jrnl/pull/1466) ([apainintheneck](https://github.com/apainintheneck))
|
||||||
|
- Give a proper message when trying to use an empty config file [\#1461](https://github.com/jrnl-org/jrnl/pull/1461) ([jonakeys](https://github.com/jonakeys))
|
||||||
|
- Display "No entry to save, because no text was received" after empty entry on cmdline [\#1459](https://github.com/jrnl-org/jrnl/pull/1459) ([apainintheneck](https://github.com/apainintheneck))
|
||||||
|
- Yaml export errors now don't show stack trace [\#1449](https://github.com/jrnl-org/jrnl/pull/1449) ([apainintheneck](https://github.com/apainintheneck))
|
||||||
|
|
||||||
**Deprecated:**
|
**Deprecated:**
|
||||||
|
|
||||||
- Remove "sample" format and its asteval dependency [\#1435](https://github.com/jrnl-org/jrnl/issues/1435)
|
- Remove "sample" format and its asteval dependency [\#1435](https://github.com/jrnl-org/jrnl/issues/1435)
|
||||||
|
@ -23,6 +34,13 @@
|
||||||
**Packaging:**
|
**Packaging:**
|
||||||
|
|
||||||
- Sync jrnl's Python version support more closely to Python release cycle [\#1406](https://github.com/jrnl-org/jrnl/issues/1406)
|
- Sync jrnl's Python version support more closely to Python release cycle [\#1406](https://github.com/jrnl-org/jrnl/issues/1406)
|
||||||
|
- Bump cryptography from 37.0.1 to 37.0.2 [\#1467](https://github.com/jrnl-org/jrnl/pull/1467) ([dependabot[bot]](https://github.com/apps/dependabot))
|
||||||
|
- Bump cryptography from 36.0.2 to 37.0.1 [\#1462](https://github.com/jrnl-org/jrnl/pull/1462) ([dependabot[bot]](https://github.com/apps/dependabot))
|
||||||
|
- Bump pytest from 7.1.1 to 7.1.2 [\#1458](https://github.com/jrnl-org/jrnl/pull/1458) ([dependabot[bot]](https://github.com/apps/dependabot))
|
||||||
|
- Bump pyproject-flake8 from 0.0.1a3 to 0.0.1a4 [\#1447](https://github.com/jrnl-org/jrnl/pull/1447) ([dependabot[bot]](https://github.com/apps/dependabot))
|
||||||
|
- Bump black from 22.1.0 to 22.3.0 [\#1442](https://github.com/jrnl-org/jrnl/pull/1442) ([dependabot[bot]](https://github.com/apps/dependabot))
|
||||||
|
- Bump mkdocs from 1.2.3 to 1.3.0 [\#1441](https://github.com/jrnl-org/jrnl/pull/1441) ([dependabot[bot]](https://github.com/apps/dependabot))
|
||||||
|
- Bump pyproject-flake8 from 0.0.1a2 to 0.0.1a3 [\#1440](https://github.com/jrnl-org/jrnl/pull/1440) ([dependabot[bot]](https://github.com/apps/dependabot))
|
||||||
- Bump pytz from 2021.3 to 2022.1 [\#1438](https://github.com/jrnl-org/jrnl/pull/1438) ([dependabot[bot]](https://github.com/apps/dependabot))
|
- Bump pytz from 2021.3 to 2022.1 [\#1438](https://github.com/jrnl-org/jrnl/pull/1438) ([dependabot[bot]](https://github.com/apps/dependabot))
|
||||||
- Bump pytest from 7.0.1 to 7.1.1 [\#1430](https://github.com/jrnl-org/jrnl/pull/1430) ([dependabot[bot]](https://github.com/apps/dependabot))
|
- Bump pytest from 7.0.1 to 7.1.1 [\#1430](https://github.com/jrnl-org/jrnl/pull/1430) ([dependabot[bot]](https://github.com/apps/dependabot))
|
||||||
- Bump cryptography from 36.0.1 to 36.0.2 [\#1427](https://github.com/jrnl-org/jrnl/pull/1427) ([dependabot[bot]](https://github.com/apps/dependabot))
|
- Bump cryptography from 36.0.1 to 36.0.2 [\#1427](https://github.com/jrnl-org/jrnl/pull/1427) ([dependabot[bot]](https://github.com/apps/dependabot))
|
||||||
|
|
|
@ -243,10 +243,10 @@ def parse_args(args=[]):
|
||||||
reading.add_argument(
|
reading.add_argument(
|
||||||
"-not",
|
"-not",
|
||||||
dest="excluded",
|
dest="excluded",
|
||||||
nargs="?",
|
nargs=1,
|
||||||
default=[],
|
default=[],
|
||||||
metavar="TAG",
|
metavar="TAG",
|
||||||
action="append",
|
action="extend",
|
||||||
help="Exclude entries with this tag",
|
help="Exclude entries with this tag",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,10 @@ def load_or_install_jrnl(alt_config_path):
|
||||||
logging.debug("Reading configuration from file %s", config_path)
|
logging.debug("Reading configuration from file %s", config_path)
|
||||||
config = load_config(config_path)
|
config = load_config(config_path)
|
||||||
|
|
||||||
|
if config is None:
|
||||||
|
print("Unable to parse config file", file=sys.stderr)
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
if is_old_version(config_path):
|
if is_old_version(config_path):
|
||||||
from jrnl import upgrade
|
from jrnl import upgrade
|
||||||
|
|
||||||
|
|
|
@ -134,11 +134,9 @@ def write_mode(args, config, journal, **kwargs):
|
||||||
else:
|
else:
|
||||||
raw = _write_in_editor(config)
|
raw = _write_in_editor(config)
|
||||||
|
|
||||||
if not raw:
|
if not raw or raw.isspace():
|
||||||
logging.error("Write mode: couldn't get raw text")
|
logging.error("Write mode: couldn't get raw text or entry was empty")
|
||||||
raise JrnlException(
|
raise JrnlException(Message(MsgText.NoTextReceived, MsgType.ERROR))
|
||||||
Message(MsgText.JrnlExceptionMessage.NoTextReceived, MsgType.ERROR)
|
|
||||||
)
|
|
||||||
|
|
||||||
logging.debug(
|
logging.debug(
|
||||||
'Write mode: appending raw text to journal "%s": %s', args.journal_name, raw
|
'Write mode: appending raw text to journal "%s": %s', args.journal_name, raw
|
||||||
|
|
|
@ -98,7 +98,7 @@ class MsgText(Enum):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
NoTextReceived = """
|
NoTextReceived = """
|
||||||
Nothing saved to file
|
No entry to save, because no text was received
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# --- Upgrade --- #
|
# --- Upgrade --- #
|
||||||
|
|
|
@ -35,6 +35,8 @@ class TextExporter:
|
||||||
return f"[Journal exported to {path}]"
|
return f"[Journal exported to {path}]"
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
return f"[{ERROR_COLOR}ERROR{RESET_COLOR}: {e.filename} {e.strerror}]"
|
return f"[{ERROR_COLOR}ERROR{RESET_COLOR}: {e.filename} {e.strerror}]"
|
||||||
|
except RuntimeError as e:
|
||||||
|
return e
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def make_filename(cls, entry):
|
def make_filename(cls, entry):
|
||||||
|
@ -54,6 +56,8 @@ class TextExporter:
|
||||||
return "[{2}ERROR{3}: {0} {1}]".format(
|
return "[{2}ERROR{3}: {0} {1}]".format(
|
||||||
e.filename, e.strerror, ERROR_COLOR, RESET_COLOR
|
e.filename, e.strerror, ERROR_COLOR, RESET_COLOR
|
||||||
)
|
)
|
||||||
|
except RuntimeError as e:
|
||||||
|
return e
|
||||||
return "[Journal exported to {}]".format(path)
|
return "[Journal exported to {}]".format(path)
|
||||||
|
|
||||||
def _slugify(string):
|
def _slugify(string):
|
||||||
|
|
|
@ -23,12 +23,10 @@ class YAMLExporter(TextExporter):
|
||||||
def export_entry(cls, entry, to_multifile=True):
|
def export_entry(cls, entry, to_multifile=True):
|
||||||
"""Returns a markdown representation of a single entry, with YAML front matter."""
|
"""Returns a markdown representation of a single entry, with YAML front matter."""
|
||||||
if to_multifile is False:
|
if to_multifile is False:
|
||||||
print(
|
raise RuntimeError(
|
||||||
f"{ERROR_COLOR}ERROR{RESET_COLOR}: YAML export must be to individual files. Please \
|
f"{ERROR_COLOR}ERROR{RESET_COLOR}: YAML export must be to individual files. Please \
|
||||||
specify a directory to export to.",
|
specify a directory to export to."
|
||||||
file=sys.stderr,
|
|
||||||
)
|
)
|
||||||
return
|
|
||||||
|
|
||||||
date_str = entry.date.strftime(entry.journal.config["timeformat"])
|
date_str = entry.date.strftime(entry.journal.config["timeformat"])
|
||||||
body_wrapper = "\n" if entry.body else ""
|
body_wrapper = "\n" if entry.body else ""
|
||||||
|
@ -131,10 +129,8 @@ class YAMLExporter(TextExporter):
|
||||||
@classmethod
|
@classmethod
|
||||||
def export_journal(cls, journal):
|
def export_journal(cls, journal):
|
||||||
"""Returns an error, as YAML export requires a directory as a target."""
|
"""Returns an error, as YAML export requires a directory as a target."""
|
||||||
print(
|
raise RuntimeError(
|
||||||
"{}ERROR{}: YAML export must be to individual files. Please specify a directory to export to.".format(
|
"{}ERROR{}: YAML export must be to individual files. Please specify a directory to export to.".format(
|
||||||
ERROR_COLOR, RESET_COLOR
|
ERROR_COLOR, RESET_COLOR
|
||||||
),
|
)
|
||||||
file=sys.stderr,
|
|
||||||
)
|
)
|
||||||
return
|
|
||||||
|
|
4
poetry.lock
generated
4
poetry.lock
generated
|
@ -412,8 +412,8 @@ python-versions = ">=3.6"
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
click = ">=3.3"
|
click = ">=3.3"
|
||||||
ghp-import = ">=1.0"
|
ghp-import = ">=1.0"
|
||||||
importlib-metadata = ">=3.10"
|
importlib-metadata = ">=4.3"
|
||||||
Jinja2 = ">=2.10.1"
|
Jinja2 = ">=2.10.2"
|
||||||
Markdown = ">=3.2.1"
|
Markdown = ">=3.2.1"
|
||||||
mergedeep = ">=1.3.4"
|
mergedeep = ">=1.3.4"
|
||||||
packaging = ">=20.5"
|
packaging = ">=20.5"
|
||||||
|
|
|
@ -85,7 +85,6 @@ Feature: Multiple journals
|
||||||
Then the output should contain "Journal encrypted to features/journals/basic_onefile.journal"
|
Then the output should contain "Journal encrypted to features/journals/basic_onefile.journal"
|
||||||
And the config should contain "encrypt: false"
|
And the config should contain "encrypt: false"
|
||||||
|
|
||||||
|
|
||||||
Scenario: Don't overwrite main config when decrypting a journal in an alternate config
|
Scenario: Don't overwrite main config when decrypting a journal in an alternate config
|
||||||
Given the config "editor_encrypted.yaml" exists
|
Given the config "editor_encrypted.yaml" exists
|
||||||
And we use the password "bad doggie no biscuit" if prompted
|
And we use the password "bad doggie no biscuit" if prompted
|
||||||
|
@ -93,3 +92,14 @@ Feature: Multiple journals
|
||||||
When we run "jrnl --cf editor_encrypted.yaml --decrypt"
|
When we run "jrnl --cf editor_encrypted.yaml --decrypt"
|
||||||
Then the config should contain "encrypt: true"
|
Then the config should contain "encrypt: true"
|
||||||
And the output should not contain "Wrong password"
|
And the output should not contain "Wrong password"
|
||||||
|
|
||||||
|
Scenario: Show an error message when the config file is empty
|
||||||
|
Given we use the config "empty_file.yaml"
|
||||||
|
When we run "jrnl -1"
|
||||||
|
Then the error output should contain "Unable to parse config file"
|
||||||
|
|
||||||
|
Scenario: Show an error message when using --config-file with empty file
|
||||||
|
Given the config "empty_file.yaml" exists
|
||||||
|
And we use the config "basic_onefile.yaml"
|
||||||
|
When we run "jrnl --cf empty_file.yaml"
|
||||||
|
Then the error output should contain "Unable to parse config file"
|
||||||
|
|
|
@ -425,6 +425,20 @@ Feature: Custom formats
|
||||||
| basic_folder.yaml |
|
| basic_folder.yaml |
|
||||||
# | basic_dayone.yaml |
|
# | basic_dayone.yaml |
|
||||||
|
|
||||||
|
Scenario Outline: Exporting YAML to nonexistent directory leads to user-friendly error with no traceback
|
||||||
|
Given we use the config "<config_file>"
|
||||||
|
And we use the password "test" if prompted
|
||||||
|
When we run "jrnl --export yaml --file nonexistent_dir"
|
||||||
|
Then the output should contain "YAML export must be to individual files"
|
||||||
|
And the output should not contain "Traceback"
|
||||||
|
|
||||||
|
Examples: configs
|
||||||
|
| config_file |
|
||||||
|
| basic_onefile.yaml |
|
||||||
|
| basic_encrypted.yaml |
|
||||||
|
| basic_folder.yaml |
|
||||||
|
| basic_dayone.yaml |
|
||||||
|
|
||||||
@skip_win # @todo YAML exporter does not correctly export emoji on Windows
|
@skip_win # @todo YAML exporter does not correctly export emoji on Windows
|
||||||
Scenario Outline: Add a blank line to YAML export if there isn't one already
|
Scenario Outline: Add a blank line to YAML export if there isn't one already
|
||||||
# https://github.com/jrnl-org/jrnl/issues/768
|
# https://github.com/jrnl-org/jrnl/issues/768
|
||||||
|
|
|
@ -73,12 +73,12 @@ Feature: Writing new entries.
|
||||||
| basic_dayone.yaml |
|
| basic_dayone.yaml |
|
||||||
| basic_folder.yaml |
|
| basic_folder.yaml |
|
||||||
|
|
||||||
Scenario Outline: Writing an empty entry from the editor should yield "Nothing saved to file" message
|
Scenario Outline: Writing an empty entry from the editor should yield "No entry to save" message
|
||||||
Given we use the config "<config_file>"
|
Given we use the config "<config_file>"
|
||||||
And we write nothing to the editor if opened
|
And we write nothing to the editor if opened
|
||||||
And we use the password "test" if prompted
|
And we use the password "test" if prompted
|
||||||
When we run "jrnl --edit"
|
When we run "jrnl --edit"
|
||||||
Then the error output should contain "Nothing saved to file"
|
Then the error output should contain "No entry to save, because no text was received"
|
||||||
And the editor should have been called
|
And the editor should have been called
|
||||||
|
|
||||||
Examples: configs
|
Examples: configs
|
||||||
|
@ -89,6 +89,20 @@ Feature: Writing new entries.
|
||||||
| basic_encrypted.yaml |
|
| basic_encrypted.yaml |
|
||||||
| basic_onefile.yaml |
|
| basic_onefile.yaml |
|
||||||
|
|
||||||
|
Scenario Outline: Writing an empty entry from the command line should yield "No entry to save" message
|
||||||
|
Given we use the config "<config_file>"
|
||||||
|
And we use the password "test" if prompted
|
||||||
|
When we run "jrnl" and enter "\x04"
|
||||||
|
Then the error output should contain "No entry to save, because no text was received"
|
||||||
|
When we run "jrnl" and enter " \t \n \x04"
|
||||||
|
Then the error output should contain "No entry to save, because no text was received"
|
||||||
|
|
||||||
|
Examples: configs
|
||||||
|
| config_file |
|
||||||
|
| basic_onefile.yaml |
|
||||||
|
| basic_encrypted.yaml |
|
||||||
|
| basic_folder.yaml |
|
||||||
|
| basic_dayone.yaml |
|
||||||
|
|
||||||
Scenario Outline: Writing an empty entry from the command line with no editor should yield nothing
|
Scenario Outline: Writing an empty entry from the command line with no editor should yield nothing
|
||||||
Given we use the config "<config_file>"
|
Given we use the config "<config_file>"
|
||||||
|
|
0
tests/data/configs/empty_file.yaml
Normal file
0
tests/data/configs/empty_file.yaml
Normal file
|
@ -101,7 +101,11 @@ def we_use_the_config(request, temp_dir, working_dir):
|
||||||
|
|
||||||
# @todo get rid of this by using default config values
|
# @todo get rid of this by using default config values
|
||||||
# merge in version number
|
# merge in version number
|
||||||
if config_file.endswith("yaml") and os.path.exists(config_dest):
|
if (
|
||||||
|
config_file.endswith("yaml")
|
||||||
|
and os.path.exists(config_dest)
|
||||||
|
and os.path.getsize(config_dest) > 0
|
||||||
|
):
|
||||||
# Add jrnl version to file for 2.x journals
|
# Add jrnl version to file for 2.x journals
|
||||||
with open(config_dest, "a") as cf:
|
with open(config_dest, "a") as cf:
|
||||||
cf.write("version: {}".format(__version__))
|
cf.write("version: {}".format(__version__))
|
||||||
|
|
|
@ -88,6 +88,12 @@ def test_end_date_alone():
|
||||||
assert expected == cli_as_dict("-to 2020-01-01")
|
assert expected == cli_as_dict("-to 2020-01-01")
|
||||||
|
|
||||||
|
|
||||||
|
def test_not_empty():
|
||||||
|
with pytest.raises(SystemExit) as wrapped_e:
|
||||||
|
cli_as_dict("-not")
|
||||||
|
assert wrapped_e.value.code == 2
|
||||||
|
|
||||||
|
|
||||||
def test_not_alone():
|
def test_not_alone():
|
||||||
assert cli_as_dict("-not test") == expected_args(excluded=["test"])
|
assert cli_as_dict("-not test") == expected_args(excluded=["test"])
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue