mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-05-10 16:48:31 +02:00
[GH-632] confirming that each journal can be parsed during upgrade, and aborting upgrade if not
[GH-632] raising exception in upgrade.py on fail Handling it in install.py to prevent config from being overwritten when upgrade fails [GH-632] removing unnecessary whitespace [GH-632] removing unreachable return statement [GH-632] adding call to action to report issue when upgrade fails
This commit is contained in:
parent
328faa401c
commit
8abbdf4db5
6 changed files with 68 additions and 30 deletions
|
@ -29,14 +29,3 @@
|
||||||
When we run "jrnl simple -n 1"
|
When we run "jrnl simple -n 1"
|
||||||
Then we should not see the message "Password"
|
Then we should not see the message "Password"
|
||||||
and the output should contain "2013-06-10 15:40 Life is good"
|
and the output should contain "2013-06-10 15:40 Life is good"
|
||||||
|
|
||||||
Scenario: Upgrading a journal encrypted with jrnl 1.x
|
|
||||||
Given we use the config "encrypted_old.json"
|
|
||||||
When we run "jrnl -n 1" and enter
|
|
||||||
"""
|
|
||||||
Y
|
|
||||||
bad doggie no biscuit
|
|
||||||
bad doggie no biscuit
|
|
||||||
"""
|
|
||||||
Then we should see the message "Password"
|
|
||||||
and the output should contain "2013-06-10 15:40 Life is good"
|
|
||||||
|
|
|
@ -43,17 +43,6 @@ Feature: Zapped bugs should stay dead.
|
||||||
| Hope to get a lot of traffic.
|
| Hope to get a lot of traffic.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Scenario: Upgrade and parse journals with square brackets
|
|
||||||
Given we use the config "upgrade_from_195.json"
|
|
||||||
When we run "jrnl -9" and enter "Y"
|
|
||||||
Then the output should contain
|
|
||||||
"""
|
|
||||||
2010-06-10 15:00 A life without chocolate is like a bad analogy.
|
|
||||||
|
|
||||||
2013-06-10 15:40 He said "[this] is the best time to be alive".
|
|
||||||
"""
|
|
||||||
Then the journal should have 2 entries
|
|
||||||
|
|
||||||
Scenario: Integers in square brackets should not be read as dates
|
Scenario: Integers in square brackets should not be read as dates
|
||||||
Given we use the config "brackets.yaml"
|
Given we use the config "brackets.yaml"
|
||||||
When we run "jrnl -1"
|
When we run "jrnl -1"
|
||||||
|
|
23
features/upgrade.feature
Normal file
23
features/upgrade.feature
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
Feature: Upgrading Journals from 1.x.x to 2.x.x
|
||||||
|
|
||||||
|
Scenario: Upgrade and parse journals with square brackets
|
||||||
|
Given we use the config "upgrade_from_195.json"
|
||||||
|
When we run "jrnl -9" and enter "Y"
|
||||||
|
Then the output should contain
|
||||||
|
"""
|
||||||
|
2010-06-10 15:00 A life without chocolate is like a bad analogy.
|
||||||
|
|
||||||
|
2013-06-10 15:40 He said "[this] is the best time to be alive".
|
||||||
|
"""
|
||||||
|
Then the journal should have 2 entries
|
||||||
|
|
||||||
|
Scenario: Upgrading a journal encrypted with jrnl 1.x
|
||||||
|
Given we use the config "encrypted_old.json"
|
||||||
|
When we run "jrnl -n 1" and enter
|
||||||
|
"""
|
||||||
|
Y
|
||||||
|
bad doggie no biscuit
|
||||||
|
bad doggie no biscuit
|
||||||
|
"""
|
||||||
|
Then we should see the message "Password"
|
||||||
|
and the output should contain "2013-06-10 15:40 Life is good"
|
|
@ -84,9 +84,20 @@ class Journal(object):
|
||||||
def write(self, filename=None):
|
def write(self, filename=None):
|
||||||
"""Dumps the journal into the config file, overwriting it"""
|
"""Dumps the journal into the config file, overwriting it"""
|
||||||
filename = filename or self.config['journal']
|
filename = filename or self.config['journal']
|
||||||
text = "\n".join([e.__unicode__() for e in self.entries])
|
text = self._to_text()
|
||||||
self._store(filename, text)
|
self._store(filename, text)
|
||||||
|
|
||||||
|
def validate_parsing(self):
|
||||||
|
"""Confirms that the jrnl is still parsed correctly after being dumped to text."""
|
||||||
|
new_entries = self._parse(self._to_text())
|
||||||
|
for i, entry in enumerate(self.entries):
|
||||||
|
if entry != new_entries[i]:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _to_text(self):
|
||||||
|
return "\n".join([e.__unicode__() for e in self.entries])
|
||||||
|
|
||||||
def _load(self, filename):
|
def _load(self, filename):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ from .Journal import PlainJournal
|
||||||
from .EncryptedJournal import EncryptedJournal
|
from .EncryptedJournal import EncryptedJournal
|
||||||
import yaml
|
import yaml
|
||||||
import logging
|
import logging
|
||||||
|
import sys
|
||||||
|
|
||||||
DEFAULT_CONFIG_NAME = 'jrnl.yaml'
|
DEFAULT_CONFIG_NAME = 'jrnl.yaml'
|
||||||
DEFAULT_JOURNAL_NAME = 'journal.txt'
|
DEFAULT_JOURNAL_NAME = 'journal.txt'
|
||||||
|
@ -85,8 +86,18 @@ def load_or_install_jrnl():
|
||||||
if os.path.exists(config_path):
|
if os.path.exists(config_path):
|
||||||
log.debug('Reading configuration from file %s', config_path)
|
log.debug('Reading configuration from file %s', config_path)
|
||||||
config = util.load_config(config_path)
|
config = util.load_config(config_path)
|
||||||
upgrade.upgrade_jrnl_if_necessary(config_path)
|
|
||||||
|
try:
|
||||||
|
upgrade.upgrade_jrnl_if_necessary(config_path)
|
||||||
|
except upgrade.UpgradeValidationException:
|
||||||
|
util.prompt("Aborting upgrade.")
|
||||||
|
util.prompt("Please tell us about this problem at the following URL:")
|
||||||
|
util.prompt("https://github.com/jrnl-org/jrnl/issues/new?title=UpgradeValidationException")
|
||||||
|
util.prompt("Exiting.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
upgrade_config(config)
|
upgrade_config(config)
|
||||||
|
|
||||||
return config
|
return config
|
||||||
else:
|
else:
|
||||||
log.debug('Configuration file not found, installing jrnl...')
|
log.debug('Configuration file not found, installing jrnl...')
|
||||||
|
|
|
@ -44,6 +44,7 @@ older versions of jrnl anymore.
|
||||||
encrypted_journals = {}
|
encrypted_journals = {}
|
||||||
plain_journals = {}
|
plain_journals = {}
|
||||||
other_journals = {}
|
other_journals = {}
|
||||||
|
all_journals = []
|
||||||
|
|
||||||
for journal_name, journal_conf in config['journals'].items():
|
for journal_name, journal_conf in config['journals'].items():
|
||||||
if isinstance(journal_conf, dict):
|
if isinstance(journal_conf, dict):
|
||||||
|
@ -85,19 +86,33 @@ older versions of jrnl anymore.
|
||||||
util.prompt("\nUpgrading encrypted '{}' journal stored in {}...".format(journal_name, path))
|
util.prompt("\nUpgrading encrypted '{}' journal stored in {}...".format(journal_name, path))
|
||||||
backup(path, binary=True)
|
backup(path, binary=True)
|
||||||
old_journal = Journal.open_journal(journal_name, util.scope_config(config, journal_name), legacy=True)
|
old_journal = Journal.open_journal(journal_name, util.scope_config(config, journal_name), legacy=True)
|
||||||
new_journal = EncryptedJournal.from_journal(old_journal)
|
all_journals.append(EncryptedJournal.from_journal(old_journal))
|
||||||
new_journal.write()
|
|
||||||
util.prompt(" Done.")
|
|
||||||
|
|
||||||
for journal_name, path in plain_journals.items():
|
for journal_name, path in plain_journals.items():
|
||||||
util.prompt("\nUpgrading plain text '{}' journal stored in {}...".format(journal_name, path))
|
util.prompt("\nUpgrading plain text '{}' journal stored in {}...".format(journal_name, path))
|
||||||
backup(path)
|
backup(path)
|
||||||
old_journal = Journal.open_journal(journal_name, util.scope_config(config, journal_name), legacy=True)
|
old_journal = Journal.open_journal(journal_name, util.scope_config(config, journal_name), legacy=True)
|
||||||
new_journal = Journal.PlainJournal.from_journal(old_journal)
|
all_journals.append(Journal.PlainJournal.from_journal(old_journal))
|
||||||
new_journal.write()
|
|
||||||
util.prompt(" Done.")
|
# loop through lists to validate
|
||||||
|
failed_journals = [j for j in all_journals if not j.validate_parsing()]
|
||||||
|
|
||||||
|
if len(failed_journals) > 0:
|
||||||
|
util.prompt("\nThe following journal{} failed to upgrade:\n{}".format(
|
||||||
|
's' if len(failed_journals) > 1 else '', "\n".join(j.name for j in failed_journals))
|
||||||
|
)
|
||||||
|
|
||||||
|
raise UpgradeValidationException
|
||||||
|
|
||||||
|
# write all journals - or - don't
|
||||||
|
for j in all_journals:
|
||||||
|
j.write()
|
||||||
|
|
||||||
util.prompt("\nUpgrading config...")
|
util.prompt("\nUpgrading config...")
|
||||||
backup(config_path)
|
backup(config_path)
|
||||||
|
|
||||||
util.prompt("\nWe're all done here and you can start enjoying jrnl 2.".format(config_path))
|
util.prompt("\nWe're all done here and you can start enjoying jrnl 2.".format(config_path))
|
||||||
|
|
||||||
|
class UpgradeValidationException(Exception):
|
||||||
|
"""Raised when the contents of an upgraded journal do not match the old journal"""
|
||||||
|
pass
|
||||||
|
|
Loading…
Add table
Reference in a new issue