diff --git a/.github/workflows/changelog.yaml b/.github/workflows/changelog.yaml index c3f8037f..f8b4eca1 100644 --- a/.github/workflows/changelog.yaml +++ b/.github/workflows/changelog.yaml @@ -152,6 +152,14 @@ jobs: git commit -m "Update changelog [ci skip]" git push origin "$BRANCH" + - name: Update tag to include changelog + if: startsWith(env.GITHUB_REF, 'refs/tags/') + run: | + # This is a tag build (releases and prereleases) + # update the tag to include the changelog + git tag -fam "$GITHUB_REF_NAME" "$GITHUB_REF_NAME" + git push --tags --force + - name: Merge to Release branch if: env.FULL_RELEASE == 'true' run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ec50c1b..f1de227b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## [Unreleased](https://github.com/jrnl-org/jrnl/) + +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v3.3...HEAD) + +**Implemented enhancements:** + +- Add `rich` handler to debug logging [\#1627](https://github.com/jrnl-org/jrnl/pull/1627) ([wren](https://github.com/wren)) + +**Deprecated:** + +- Drop Python 3.9 and use Python 3.11 official release [\#1611](https://github.com/jrnl-org/jrnl/pull/1611) ([micahellison](https://github.com/micahellison)) + +**Build:** + +- Fix bug where changelog is always slightly out of date on release tags [\#1631](https://github.com/jrnl-org/jrnl/pull/1631) ([wren](https://github.com/wren)) + +**Documentation:** + +- Document that editors must be blocking processes [\#1624](https://github.com/jrnl-org/jrnl/pull/1624) ([micahellison](https://github.com/micahellison)) + ## [v3.3](https://pypi.org/project/jrnl/v3.3/) (2022-10-29) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v3.3-beta2...v3.3) diff --git a/docs/encryption.md b/docs/encryption.md index 6dae9a48..b019e4a6 100644 --- a/docs/encryption.md +++ b/docs/encryption.md @@ -100,16 +100,16 @@ something like `pip3 install crytography`) import base64 import getpass from pathlib import Path + from cryptography.fernet import Fernet from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC - filepath = input("journal file path: ") password = getpass.getpass("Password: ") -with open(Path(filepath),"rb") as f: +with open(Path(filepath), "rb") as f: ciphertext = f.read() password = password.encode("utf-8") @@ -123,7 +123,7 @@ kdf = PBKDF2HMAC( key = base64.urlsafe_b64encode(kdf.derive(password)) -print(Fernet(key).decrypt(ciphertext).decode('utf-8')) +print(Fernet(key).decrypt(ciphertext).decode("utf-8")) ``` **Example for jrnl v1 files**: @@ -137,18 +137,19 @@ like `pip3 install pycrypto`) """ import argparse -from Crypto.Cipher import AES import getpass import hashlib +from Crypto.Cipher import AES + parser = argparse.ArgumentParser() parser.add_argument("filepath", help="journal file to decrypt") args = parser.parse_args() pwd = getpass.getpass() -key = hashlib.sha256(pwd.encode('utf-8')).digest() +key = hashlib.sha256(pwd.encode("utf-8")).digest() -with open(args.filepath, 'rb') as f: +with open(args.filepath, "rb") as f: ciphertext = f.read() crypto = AES.new(key, AES.MODE_CBC, ciphertext[:16]) diff --git a/jrnl/cli.py b/jrnl/cli.py index 7c692c4f..d8009df6 100644 --- a/jrnl/cli.py +++ b/jrnl/cli.py @@ -5,6 +5,8 @@ import logging import sys import traceback +from rich.logging import RichHandler + from jrnl.args import parse_args from jrnl.exception import JrnlException from jrnl.jrnl import run @@ -21,7 +23,9 @@ def configure_logger(debug=False): logging.basicConfig( level=logging.DEBUG, - format="%(levelname)-8s %(name)-12s %(message)s", + datefmt="[%X]", + format="%(message)s", + handlers=[RichHandler()], ) logging.getLogger("parsedatetime").setLevel(logging.INFO) logging.getLogger("keyring.backend").setLevel(logging.ERROR) @@ -34,7 +38,7 @@ def cli(manual_args=None): args = parse_args(manual_args) configure_logger(args.debug) - logging.debug("Parsed args: %s", args) + logging.debug("Parsed args:\n%s", args) status_code = run(args) diff --git a/jrnl/config.py b/jrnl/config.py index 8e5c5a14..e3290d8b 100644 --- a/jrnl/config.py +++ b/jrnl/config.py @@ -8,6 +8,7 @@ from typing import Callable import colorama import xdg.BaseDirectory +from rich.pretty import pretty_repr from ruamel.yaml import YAML from ruamel.yaml import constructor @@ -126,12 +127,15 @@ def scope_config(config, journal_name): if type(journal_conf) is dict: # We can override the default config on a by-journal basis logging.debug( - "Updating configuration with specific journal overrides %s", journal_conf + "Updating configuration with specific journal overrides:\n%s", + pretty_repr(journal_conf), ) config.update(journal_conf) else: # But also just give them a string to point to the journal file config["journal"] = journal_conf + + logging.debug("Scoped config:\n%s", pretty_repr(config)) return config diff --git a/jrnl/install.py b/jrnl/install.py index b20685f0..be0c7bc3 100644 --- a/jrnl/install.py +++ b/jrnl/install.py @@ -6,6 +6,8 @@ import logging import os import sys +from rich.pretty import pretty_repr + from jrnl.config import DEFAULT_JOURNAL_KEY from jrnl.config import get_config_path from jrnl.config import get_default_config @@ -101,7 +103,7 @@ def load_or_install_jrnl(alt_config_path): logging.debug("Configuration file not found, installing jrnl...") config = install() - logging.debug('Using configuration "%s"', config) + logging.debug('Using configuration:\n"%s"', pretty_repr(config)) return config diff --git a/poetry.lock b/poetry.lock index b7e6fc30..9b4d4c65 100644 --- a/poetry.lock +++ b/poetry.lock @@ -237,6 +237,34 @@ mccabe = ">=0.6.0,<0.7.0" pycodestyle = ">=2.8.0,<2.9.0" pyflakes = ">=2.4.0,<2.5.0" +[[package]] +name = "flake8-black" +version = "0.3.3" +description = "flake8 plugin to call black as a code style validator" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +black = ">=22.1.0" +flake8 = ">=3.0.0" +tomli = "*" + +[[package]] +name = "flake8-isort" +version = "5.0.0" +description = "flake8 plugin that integrates isort ." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +flake8 = "*" +isort = ">=4.3.5,<6" + +[package.extras] +test = ["pytest"] + [[package]] name = "flake8-type-checking" version = "2.2.0" @@ -1150,7 +1178,7 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>= [metadata] lock-version = "1.1" python-versions = ">=3.10.0, <3.13" -content-hash = "c927c7c2bff0ae139d7b22a96d5cef97064e9d586e977b4d19f5ba905de602f1" +content-hash = "63f39baa62c8641eb6329472de340a9f06d9ffea3096a4095e90f98ce2986f91" [metadata.files] ansiwrap = [ @@ -1343,6 +1371,14 @@ flake8 = [ {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, ] +flake8-black = [ + {file = "flake8-black-0.3.3.tar.gz", hash = "sha256:8211f5e20e954cb57c709acccf2f3281ce27016d4c4b989c3e51f878bb7ce12a"}, + {file = "flake8_black-0.3.3-py3-none-any.whl", hash = "sha256:7d667d0059fd1aa468de1669d77cc934b7f1feeac258d57bdae69a8e73c4cd90"}, +] +flake8-isort = [ + {file = "flake8-isort-5.0.0.tar.gz", hash = "sha256:e336f928c7edc509684930ab124414194b7f4e237c712af8fcbdf49d8747b10c"}, + {file = "flake8_isort-5.0.0-py3-none-any.whl", hash = "sha256:c73f9cbd1bf209887f602a27b827164ccfeba1676801b2aa23cb49051a1be79c"}, +] flake8-type-checking = [ {file = "flake8_type_checking-2.2.0-py3-none-any.whl", hash = "sha256:c7d9d7adc6cd635a5a1a7859e5e0140f4f8f1705982a22db45872dd9acd49753"}, {file = "flake8_type_checking-2.2.0.tar.gz", hash = "sha256:f7972fc9102f3f632ace1f4b1c5c20b900b8b7b529f04bb6c1fe0a11801e9658"}, diff --git a/pyproject.toml b/pyproject.toml index 1cc84cea..e3c5592f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,6 +45,8 @@ tzlocal = ">=4.0" # https://github.com/regebro/tzlocal/blob/master/CHANGES.txt [tool.poetry.dev-dependencies] black = { version = ">=21.5b2", allow-prereleases = true } flakeheaven = ">=3.0" +flake8-black = ">=0.3.3" +flake8-isort = ">=5.0.0" flake8-type-checking = ">=2.2.0" ipdb = "*" isort = ">=5.10" @@ -63,26 +65,6 @@ xmltodict = "*" jrnl = 'jrnl.cli:cli' [tool.poe.tasks] -format-run = [ - {cmd = "black ."}, -] -format-check = [ - {cmd = "black --version"}, - {cmd = "black --check --diff ."}, -] -style-check = [ - {cmd = "flakeheaven --version"}, - {cmd = "flakeheaven plugins"}, - {cmd = "flakeheaven lint"}, -] -sort-run = [ - {cmd = "isort ."}, -] -sort-check = [ - {cmd = "isort --version"}, - {cmd = "isort --check ."}, -] - docs-check.default_item_type = "script" docs-check.sequence = [ "tasks:delete_files(['sitemap.xml', 'config.json'])", @@ -101,22 +83,23 @@ test-run = [ {cmd = "tox -q -e py --"}, ] -installer-check = [ - {cmd = "poetry --version"}, - {cmd = "poetry check"}, +# Groups of tasks +format.default_item_type = "cmd" +format.sequence = [ + "isort .", + "black .", ] -# Groups of tasks -format = [ - "format-run", - "sort-run", -] -lint = [ - "installer-check", - "style-check", - "sort-check", - "format-check", +lint.env = { FLAKEHEAVEN_CACHE_TIMEOUT = "0" } +lint.default_item_type = "cmd" +lint.sequence = [ + "poetry --version", + "poetry check", + "flakeheaven --version", + "flakeheaven plugins", + "flakeheaven lint", ] + test = [ "lint", "test-run", @@ -171,6 +154,7 @@ pycodestyle = [ "-W1*", "-W2*", "-W3*", "-W5*", ] "flake8-*" = ["+*"] +flake8-black = ["-BLK901"] [build-system] diff --git a/tests/bdd/features/encrypt.feature b/tests/bdd/features/encrypt.feature index 5c201361..b5ef1126 100644 --- a/tests/bdd/features/encrypt.feature +++ b/tests/bdd/features/encrypt.feature @@ -46,6 +46,22 @@ Feature: Encrypting and decrypting journals Then we should be prompted for a password And the output should contain "2013-06-10 15:40 Life is good" + Scenario: Encrypt journal twice and get prompted each time + Given we use the config "simple.yaml" + When we run "jrnl --encrypt" and enter + swordfish + swordfish + y + Then we should get no error + And the output should contain "Journal encrypted" + When we run "jrnl --encrypt" and enter + swordfish + swordfish + y + Then we should get no error + And the output should contain "Journal default is already encrypted. Create a new password." + And we should be prompted for a password + And the config for journal "default" should contain "encrypt: true" Scenario Outline: Running jrnl with encrypt: true on unencryptable journals Given we use the config ""