mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-05-10 16:48:31 +02:00
Merge branch 'develop' into mode-actions-1639
Conflicts: jrnl/controller.py
This commit is contained in:
commit
15a5b143ee
12 changed files with 1558 additions and 1400 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -57,6 +57,16 @@
|
||||||
|
|
||||||
**Packaging:**
|
**Packaging:**
|
||||||
|
|
||||||
|
- Update dependency cryptography to v40 [\#1710](https://github.com/jrnl-org/jrnl/pull/1710) ([renovate[bot]](https://github.com/apps/renovate))
|
||||||
|
- Update dependency poethepoet to v0.19.0 [\#1709](https://github.com/jrnl-org/jrnl/pull/1709) ([renovate[bot]](https://github.com/apps/renovate))
|
||||||
|
- Update dependency tzlocal to v4.3 [\#1708](https://github.com/jrnl-org/jrnl/pull/1708) ([renovate[bot]](https://github.com/apps/renovate))
|
||||||
|
- Update dependency tox to v4.4.7 [\#1707](https://github.com/jrnl-org/jrnl/pull/1707) ([renovate[bot]](https://github.com/apps/renovate))
|
||||||
|
- Update dependency rich to v13.3.2 [\#1706](https://github.com/jrnl-org/jrnl/pull/1706) ([renovate[bot]](https://github.com/apps/renovate))
|
||||||
|
- Update dependency pytest-xdist to v3.2.1 [\#1705](https://github.com/jrnl-org/jrnl/pull/1705) ([renovate[bot]](https://github.com/apps/renovate))
|
||||||
|
- Update dependency pytest to v7.2.2 [\#1704](https://github.com/jrnl-org/jrnl/pull/1704) ([renovate[bot]](https://github.com/apps/renovate))
|
||||||
|
- Update dependency ipdb to v0.13.13 [\#1703](https://github.com/jrnl-org/jrnl/pull/1703) ([renovate[bot]](https://github.com/apps/renovate))
|
||||||
|
- Update dependency flake8-type-checking to v2.3.1 [\#1702](https://github.com/jrnl-org/jrnl/pull/1702) ([renovate[bot]](https://github.com/apps/renovate))
|
||||||
|
- Update dependency cryptography to v39.0.2 [\#1701](https://github.com/jrnl-org/jrnl/pull/1701) ([renovate[bot]](https://github.com/apps/renovate))
|
||||||
- Update dependency rich to v13 [\#1654](https://github.com/jrnl-org/jrnl/pull/1654) ([renovate[bot]](https://github.com/apps/renovate))
|
- Update dependency rich to v13 [\#1654](https://github.com/jrnl-org/jrnl/pull/1654) ([renovate[bot]](https://github.com/apps/renovate))
|
||||||
|
|
||||||
## [v3.3](https://pypi.org/project/jrnl/v3.3/) (2022-10-29)
|
## [v3.3](https://pypi.org/project/jrnl/v3.3/) (2022-10-29)
|
||||||
|
|
|
@ -74,39 +74,45 @@ jrnlimport () {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Using templates
|
## Using Templates
|
||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
Templates require an [external editor](./advanced.md) be configured.
|
Templates require an [external editor](./advanced.md) be configured.
|
||||||
|
|
||||||
A template is a code snippet that makes it easier to use repeated text
|
Templates are text files that are used for creating structured journals.
|
||||||
each time a new journal entry is started. There are two ways you can utilize
|
There are three ways you can use templates:
|
||||||
templates in your entries.
|
|
||||||
|
|
||||||
### 1. Command line arguments
|
### 1. Use the `--template` command line argument and the default $XDG_DATA_HOME/jrnl/templates directory
|
||||||
|
|
||||||
If you had a `template.txt` file with the following contents:
|
`$XDG_DATA_HOME/jrnl/templates` is created by default to store your templates! Create a template (like `default.md`) in this directory and pass `--template FILE_IN_DIR`.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
jrnl --template default.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Use the `--template` command line argument with a local / absolute path
|
||||||
|
|
||||||
|
You can create a template file with any text. Here is an example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# /tmp/template.txt
|
||||||
My Personal Journal
|
My Personal Journal
|
||||||
Title:
|
Title:
|
||||||
|
|
||||||
Body:
|
Body:
|
||||||
```
|
```
|
||||||
|
|
||||||
The `template.txt` file could be used to create a new entry with these
|
Then, pass the absolute or relative path to the template file as an argument, and your external
|
||||||
command line arguments:
|
editor will open and have your template pre-populated.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
jrnl < template.txt # Imports template.txt as the most recent entry
|
jrnl --template /tmp/template.md
|
||||||
jrnl -1 --edit # Opens the most recent entry in the editor
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Include the template file in `jrnl.yaml`
|
### 3. Set a default template file in `jrnl.yaml`
|
||||||
|
|
||||||
A more efficient way to work with a template file is to declare the file
|
If you want a template by default, change the value of `template` in the [config file](./reference-config-file.md)
|
||||||
in your [config file](./reference-config-file.md) by changing the `template`
|
from `false` to the template file's path, wrapped in double quotes:
|
||||||
setting from `false` to the template file's path in double quotes:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
...
|
...
|
||||||
|
@ -114,9 +120,6 @@ template: "/path/to/template.txt"
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
Changes can be saved as you continue writing the journal entry and will be
|
|
||||||
logged as a new entry in the journal you specified in the original argument.
|
|
||||||
|
|
||||||
!!! tip
|
!!! tip
|
||||||
To read your journal entry or to verify the entry saved, you can use this
|
To read your journal entry or to verify the entry saved, you can use this
|
||||||
command: `jrnl -n 1` (Check out [Formats](./formats.md) for more options).
|
command: `jrnl -n 1` (Check out [Formats](./formats.md) for more options).
|
||||||
|
@ -219,4 +222,3 @@ To cause vi to jump to the end of the last line of the entry you edit, in your c
|
||||||
```yaml
|
```yaml
|
||||||
editor: vi + -c "call cursor('.',strwidth(getline('.')))"
|
editor: vi + -c "call cursor('.',strwidth(getline('.')))"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -211,6 +211,11 @@ def parse_args(args: list[str] = []) -> argparse.Namespace:
|
||||||
"Writing", textwrap.dedent(compose_msg).strip()
|
"Writing", textwrap.dedent(compose_msg).strip()
|
||||||
)
|
)
|
||||||
composing.add_argument("text", metavar="", nargs="*")
|
composing.add_argument("text", metavar="", nargs="*")
|
||||||
|
composing.add_argument(
|
||||||
|
"--template",
|
||||||
|
dest="template",
|
||||||
|
help="Path to template file. Can be a local path, absolute path, or a path relative to $XDG_DATA_HOME/jrnl/templates/",
|
||||||
|
)
|
||||||
|
|
||||||
read_msg = (
|
read_msg = (
|
||||||
"To find entries from your journal, use any combination of the below filters."
|
"To find entries from your journal, use any combination of the below filters."
|
||||||
|
@ -419,7 +424,7 @@ def parse_args(args: list[str] = []) -> argparse.Namespace:
|
||||||
default="",
|
default="",
|
||||||
help="""
|
help="""
|
||||||
Overrides default (created when first installed) config file for this command only.
|
Overrides default (created when first installed) config file for this command only.
|
||||||
|
|
||||||
Examples: \n
|
Examples: \n
|
||||||
\t - Use a work config file for this jrnl entry, call: \n
|
\t - Use a work config file for this jrnl entry, call: \n
|
||||||
\t jrnl --config-file /home/user1/work_config.yaml
|
\t jrnl --config-file /home/user1/work_config.yaml
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
|
@ -72,9 +73,9 @@ def save_config(config: dict, alt_config_path: str | None = None) -> None:
|
||||||
yaml.dump(config, f)
|
yaml.dump(config, f)
|
||||||
|
|
||||||
|
|
||||||
def get_config_path() -> str:
|
def get_config_directory() -> str:
|
||||||
try:
|
try:
|
||||||
config_directory_path = xdg.BaseDirectory.save_config_path(XDG_RESOURCE)
|
return xdg.BaseDirectory.save_config_path(XDG_RESOURCE)
|
||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
raise JrnlException(
|
raise JrnlException(
|
||||||
Message(
|
Message(
|
||||||
|
@ -88,7 +89,13 @@ def get_config_path() -> str:
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
return os.path.join(config_directory_path or home_dir(), DEFAULT_CONFIG_NAME)
|
|
||||||
|
def get_config_path() -> Path:
|
||||||
|
try:
|
||||||
|
config_directory_path = get_config_directory()
|
||||||
|
except JrnlException:
|
||||||
|
return Path(home_dir(), DEFAULT_CONFIG_NAME)
|
||||||
|
return Path(config_directory_path, DEFAULT_CONFIG_NAME)
|
||||||
|
|
||||||
|
|
||||||
def get_default_config() -> dict[str, Any]:
|
def get_default_config() -> dict[str, Any]:
|
||||||
|
@ -128,6 +135,15 @@ def get_default_journal_path() -> str:
|
||||||
return os.path.join(journal_data_path, DEFAULT_JOURNAL_NAME)
|
return os.path.join(journal_data_path, DEFAULT_JOURNAL_NAME)
|
||||||
|
|
||||||
|
|
||||||
|
def get_templates_path() -> Path:
|
||||||
|
# jrnl_xdg_resource_path is created by save_data_path if it does not exist
|
||||||
|
jrnl_xdg_resource_path = Path(xdg.BaseDirectory.save_data_path(XDG_RESOURCE))
|
||||||
|
jrnl_templates_path = jrnl_xdg_resource_path / "templates"
|
||||||
|
# Create the directory if needed.
|
||||||
|
jrnl_templates_path.mkdir(exist_ok=True)
|
||||||
|
return jrnl_templates_path
|
||||||
|
|
||||||
|
|
||||||
def scope_config(config: dict, journal_name: str) -> dict:
|
def scope_config(config: dict, journal_name: str) -> dict:
|
||||||
if journal_name not in config["journals"]:
|
if journal_name not in config["journals"]:
|
||||||
return config
|
return config
|
||||||
|
|
|
@ -11,6 +11,7 @@ from jrnl import time
|
||||||
from jrnl.config import DEFAULT_JOURNAL_KEY
|
from jrnl.config import DEFAULT_JOURNAL_KEY
|
||||||
from jrnl.config import get_config_path
|
from jrnl.config import get_config_path
|
||||||
from jrnl.config import get_journal_name
|
from jrnl.config import get_journal_name
|
||||||
|
from jrnl.config import get_templates_path
|
||||||
from jrnl.config import scope_config
|
from jrnl.config import scope_config
|
||||||
from jrnl.editor import get_text_from_editor
|
from jrnl.editor import get_text_from_editor
|
||||||
from jrnl.editor import get_text_from_stdin
|
from jrnl.editor import get_text_from_stdin
|
||||||
|
@ -22,7 +23,7 @@ from jrnl.messages import MsgText
|
||||||
from jrnl.output import print_msg
|
from jrnl.output import print_msg
|
||||||
from jrnl.output import print_msgs
|
from jrnl.output import print_msgs
|
||||||
from jrnl.override import apply_overrides
|
from jrnl.override import apply_overrides
|
||||||
from jrnl.path import expand_path
|
from jrnl.path import absolute_path
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
|
@ -129,9 +130,78 @@ def _is_append_mode(args: "Namespace", config: dict, **kwargs) -> bool:
|
||||||
return append_mode
|
return append_mode
|
||||||
|
|
||||||
|
|
||||||
|
def _read_template_file(template_arg: str, template_path_from_config: str) -> str:
|
||||||
|
"""
|
||||||
|
This function is called when either a template file is passed with --template, or config.template is set.
|
||||||
|
|
||||||
|
The processing logic is:
|
||||||
|
If --template was not used: Load the global template file.
|
||||||
|
If --template was used:
|
||||||
|
* Check $XDG_DATA_HOME/jrnl/templates/template_arg.
|
||||||
|
* Check template_arg as an absolute / relative path.
|
||||||
|
|
||||||
|
If a file is found, its contents are returned as a string.
|
||||||
|
If not, a JrnlException is raised.
|
||||||
|
"""
|
||||||
|
logging.debug(
|
||||||
|
"Write mode: Either a template arg was passed, or the global config is set."
|
||||||
|
)
|
||||||
|
|
||||||
|
# If filename is unset, we are in this flow due to a global template being configured
|
||||||
|
if not template_arg:
|
||||||
|
logging.debug("Write mode: Global template configuration detected.")
|
||||||
|
global_template_path = absolute_path(template_path_from_config)
|
||||||
|
try:
|
||||||
|
with open(global_template_path, encoding="utf-8") as f:
|
||||||
|
template_data = f.read()
|
||||||
|
return template_data
|
||||||
|
except FileNotFoundError:
|
||||||
|
raise JrnlException(
|
||||||
|
Message(
|
||||||
|
MsgText.CantReadTemplateGlobalConfig,
|
||||||
|
MsgStyle.ERROR,
|
||||||
|
{
|
||||||
|
"global_template_path": global_template_path,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else: # A template CLI arg was passed.
|
||||||
|
logging.debug("Trying to load template from $XDG_DATA_HOME/jrnl/templates/")
|
||||||
|
jrnl_template_dir = get_templates_path()
|
||||||
|
logging.debug(f"Write mode: jrnl templates directory: {jrnl_template_dir}")
|
||||||
|
template_path = jrnl_template_dir / template_arg
|
||||||
|
try:
|
||||||
|
with open(template_path, encoding="utf-8") as f:
|
||||||
|
template_data = f.read()
|
||||||
|
return template_data
|
||||||
|
except FileNotFoundError:
|
||||||
|
logging.debug(
|
||||||
|
f"Couldn't open {template_path}. Treating --template argument like a local / abs path."
|
||||||
|
)
|
||||||
|
pass
|
||||||
|
|
||||||
|
normalized_template_arg_filepath = absolute_path(template_arg)
|
||||||
|
try:
|
||||||
|
with open(normalized_template_arg_filepath, encoding="utf-8") as f:
|
||||||
|
template_data = f.read()
|
||||||
|
return template_data
|
||||||
|
except FileNotFoundError:
|
||||||
|
raise JrnlException(
|
||||||
|
Message(
|
||||||
|
MsgText.CantReadTemplateCLIArg,
|
||||||
|
MsgStyle.ERROR,
|
||||||
|
{
|
||||||
|
"normalized_template_arg_filepath": normalized_template_arg_filepath,
|
||||||
|
"jrnl_template_dir": template_path,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def append_mode(args: "Namespace", config: dict, journal: "Journal", **kwargs) -> None:
|
def append_mode(args: "Namespace", config: dict, journal: "Journal", **kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
Gets input from the user to write to the journal
|
Gets input from the user to write to the journal
|
||||||
|
0. Check for a template passed as an argument, or in the global config
|
||||||
1. Check for input from cli
|
1. Check for input from cli
|
||||||
2. Check input being piped in
|
2. Check input being piped in
|
||||||
3. Open editor if configured (prepopulated with template if available)
|
3. Open editor if configured (prepopulated with template if available)
|
||||||
|
@ -140,8 +210,16 @@ def append_mode(args: "Namespace", config: dict, journal: "Journal", **kwargs) -
|
||||||
"""
|
"""
|
||||||
logging.debug("Append mode: starting")
|
logging.debug("Append mode: starting")
|
||||||
|
|
||||||
if args.text:
|
if args.template or config["template"]:
|
||||||
logging.debug("Append mode: cli text detected: %s", args.text)
|
logging.debug(f"Write mode: template CLI arg detected: {args.template}")
|
||||||
|
# Read template file and pass as raw text into the composer
|
||||||
|
template_data = _read_template_file(args.template, config["template"])
|
||||||
|
raw = _write_in_editor(config, template_data)
|
||||||
|
if raw == template_data:
|
||||||
|
logging.error("Write mode: raw text was the same as the template")
|
||||||
|
raise JrnlException(Message(MsgText.NoChangesToTemplate, MsgStyle.NORMAL))
|
||||||
|
elif args.text:
|
||||||
|
logging.debug(f"Write mode: cli text detected: {args.text}")
|
||||||
raw = " ".join(args.text).strip()
|
raw = " ".join(args.text).strip()
|
||||||
if args.edit:
|
if args.edit:
|
||||||
raw = _write_in_editor(config, raw)
|
raw = _write_in_editor(config, raw)
|
||||||
|
@ -156,9 +234,6 @@ def append_mode(args: "Namespace", config: dict, journal: "Journal", **kwargs) -
|
||||||
if not raw or raw.isspace():
|
if not raw or raw.isspace():
|
||||||
logging.error("Append mode: couldn't get raw text or entry was empty")
|
logging.error("Append mode: couldn't get raw text or entry was empty")
|
||||||
raise JrnlException(Message(MsgText.NoTextReceived, MsgStyle.NORMAL))
|
raise JrnlException(Message(MsgText.NoTextReceived, MsgStyle.NORMAL))
|
||||||
if config["template"] and raw == _get_editor_template(config):
|
|
||||||
logging.error("Write mode: raw text was the same as the template")
|
|
||||||
raise JrnlException(Message(MsgText.NoChangesToTemplate, MsgStyle.NORMAL))
|
|
||||||
|
|
||||||
logging.debug(
|
logging.debug(
|
||||||
f"Append mode: appending raw text to journal '{args.journal_name}': {raw}"
|
f"Append mode: appending raw text to journal '{args.journal_name}': {raw}"
|
||||||
|
@ -192,46 +267,18 @@ def search_mode(args: "Namespace", journal: "Journal", **kwargs) -> None:
|
||||||
_filter_journal_entries(args, journal)
|
_filter_journal_entries(args, journal)
|
||||||
|
|
||||||
|
|
||||||
def _write_in_editor(config: dict, template: str | None = None) -> str:
|
def _write_in_editor(config: dict, prepopulated_text: str | None = None) -> str:
|
||||||
if config["editor"]:
|
if config["editor"]:
|
||||||
logging.debug("Append mode: opening editor")
|
logging.debug("Write mode: opening editor")
|
||||||
if not template:
|
raw = get_text_from_editor(config, prepopulated_text)
|
||||||
template = _get_editor_template(config)
|
|
||||||
raw = get_text_from_editor(config, template)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raw = get_text_from_stdin()
|
raw = get_text_from_stdin()
|
||||||
|
|
||||||
return raw
|
return raw
|
||||||
|
|
||||||
|
|
||||||
def _get_editor_template(config: dict, **kwargs) -> str:
|
|
||||||
logging.debug("Append mode: loading template for entry")
|
|
||||||
|
|
||||||
if not config["template"]:
|
def _filter_journal_entries(args: "Namespace", journal: Journal, **kwargs) -> None:
|
||||||
logging.debug("Append mode: no template configured")
|
|
||||||
return ""
|
|
||||||
|
|
||||||
template_path = expand_path(config["template"])
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(template_path) as f:
|
|
||||||
template = f.read()
|
|
||||||
logging.debug("Append mode: template loaded: %s", template)
|
|
||||||
except OSError:
|
|
||||||
logging.error("Append mode: template not loaded")
|
|
||||||
raise JrnlException(
|
|
||||||
Message(
|
|
||||||
MsgText.CantReadTemplate,
|
|
||||||
MsgStyle.ERROR,
|
|
||||||
{"template": template_path},
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return template
|
|
||||||
|
|
||||||
|
|
||||||
def _filter_journal_entries(args: "Namespace", journal: "Journal", **kwargs) -> None:
|
|
||||||
"""Filter journal entries in-place based upon search args"""
|
"""Filter journal entries in-place based upon search args"""
|
||||||
if args.on_date:
|
if args.on_date:
|
||||||
args.start_date = args.end_date = args.on_date
|
args.start_date = args.end_date = args.on_date
|
||||||
|
@ -380,6 +427,7 @@ def _change_time_search_results(
|
||||||
args: "Namespace",
|
args: "Namespace",
|
||||||
journal: "Journal",
|
journal: "Journal",
|
||||||
old_entries: list["Entry"],
|
old_entries: list["Entry"],
|
||||||
|
no_prompt: bool = False,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> None:
|
) -> None:
|
||||||
# separate entries we are not editing
|
# separate entries we are not editing
|
||||||
|
|
|
@ -105,10 +105,16 @@ class MsgText(Enum):
|
||||||
|
|
||||||
KeyboardInterruptMsg = "Aborted by user"
|
KeyboardInterruptMsg = "Aborted by user"
|
||||||
|
|
||||||
CantReadTemplate = """
|
CantReadTemplateGlobalConfig = """
|
||||||
Unreadable template
|
Could not read template file defined in config:
|
||||||
Could not read template file at:
|
{global_template_path}
|
||||||
{template}
|
"""
|
||||||
|
|
||||||
|
CantReadTemplateCLIArg = """
|
||||||
|
Unable to find a template file based on the passed arg, and no global template was detected.
|
||||||
|
The following filepaths were checked:
|
||||||
|
jrnl XDG Template Directory : {jrnl_template_dir}
|
||||||
|
Local Filepath : {normalized_template_arg_filepath}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
NoNamedJournal = "No '{journal_name}' journal configured\n{journals}"
|
NoNamedJournal = "No '{journal_name}' journal configured\n{journals}"
|
||||||
|
|
2667
poetry.lock
generated
2667
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -31,4 +31,47 @@ Feature: Using templates
|
||||||
| basic_onefile.yaml |
|
| basic_onefile.yaml |
|
||||||
| basic_encrypted.yaml |
|
| basic_encrypted.yaml |
|
||||||
| basic_folder.yaml |
|
| basic_folder.yaml |
|
||||||
| basic_dayone.yaml |
|
| basic_dayone.yaml |
|
||||||
|
|
||||||
|
Scenario Outline: --template nonexistent_file should throw an error
|
||||||
|
Given we use the config "<config_file>"
|
||||||
|
And we use the password "test" if prompted
|
||||||
|
When we run "jrnl --template this_template_does_not_exist.template"
|
||||||
|
Then we should get an error
|
||||||
|
Then the error output should contain "Unable to find a template file based on the passed arg"
|
||||||
|
|
||||||
|
Examples: configs
|
||||||
|
| config_file |
|
||||||
|
| basic_onefile.yaml |
|
||||||
|
| basic_encrypted.yaml |
|
||||||
|
| basic_folder.yaml |
|
||||||
|
| basic_dayone.yaml |
|
||||||
|
|
||||||
|
Scenario Outline: --template local_filepath should be used in new entry
|
||||||
|
Given we use the config "<config_file>"
|
||||||
|
And we use the password "test" if prompted
|
||||||
|
When we run "jrnl --template features/templates/basic.template"
|
||||||
|
Then the output should contain "No entry to save, because the template was not changed"
|
||||||
|
|
||||||
|
Examples: configs
|
||||||
|
| config_file |
|
||||||
|
| basic_onefile.yaml |
|
||||||
|
| basic_encrypted.yaml |
|
||||||
|
| basic_folder.yaml |
|
||||||
|
| basic_dayone.yaml |
|
||||||
|
|
||||||
|
Scenario Outline: --template file_in_XDG_templates_dir should be used in new entry
|
||||||
|
Given we use the config "<config_file>"
|
||||||
|
And we use the password "test" if prompted
|
||||||
|
And we copy the template "basic.template" to the default templates folder
|
||||||
|
When we run "jrnl --template basic.template"
|
||||||
|
Then the output should contain "No entry to save, because the template was not changed"
|
||||||
|
|
||||||
|
|
||||||
|
Examples: configs
|
||||||
|
| config_file |
|
||||||
|
| basic_onefile.yaml |
|
||||||
|
| basic_encrypted.yaml |
|
||||||
|
| basic_folder.yaml |
|
||||||
|
| basic_dayone.yaml |
|
||||||
|
| basic_dayone.yaml |
|
||||||
|
|
|
@ -89,6 +89,7 @@ def cli_run(
|
||||||
mock_user_input,
|
mock_user_input,
|
||||||
mock_overrides,
|
mock_overrides,
|
||||||
mock_default_journal_path,
|
mock_default_journal_path,
|
||||||
|
mock_default_templates_path,
|
||||||
):
|
):
|
||||||
# Check if we need more mocks
|
# Check if we need more mocks
|
||||||
mock_factories.update(mock_args)
|
mock_factories.update(mock_args)
|
||||||
|
@ -98,6 +99,7 @@ def cli_run(
|
||||||
mock_factories.update(mock_config_path)
|
mock_factories.update(mock_config_path)
|
||||||
mock_factories.update(mock_user_input)
|
mock_factories.update(mock_user_input)
|
||||||
mock_factories.update(mock_default_journal_path)
|
mock_factories.update(mock_default_journal_path)
|
||||||
|
mock_factories.update(mock_default_templates_path)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"status": 0,
|
"status": 0,
|
||||||
|
@ -179,6 +181,16 @@ def mock_default_journal_path(temp_dir):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def mock_default_templates_path(temp_dir):
|
||||||
|
templates_path = Path(temp_dir.name, "templates")
|
||||||
|
return {
|
||||||
|
"get_templates_path": lambda: patch(
|
||||||
|
"jrnl.controller.get_templates_path", return_value=templates_path
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture
|
||||||
def temp_dir():
|
def temp_dir():
|
||||||
return tempfile.TemporaryDirectory()
|
return tempfile.TemporaryDirectory()
|
||||||
|
|
|
@ -125,6 +125,19 @@ def we_use_the_config(request, temp_dir, working_dir, config_file):
|
||||||
return config_dest
|
return config_dest
|
||||||
|
|
||||||
|
|
||||||
|
@given(parse('we copy the template "{template_file}" to the default templates folder'), target_fixture="default_templates_path")
|
||||||
|
def we_copy_the_template(request, temp_dir, working_dir, template_file):
|
||||||
|
# Move into temp dir as cwd
|
||||||
|
os.chdir(temp_dir.name) # @todo move this step to a more universal place
|
||||||
|
|
||||||
|
# Copy template over
|
||||||
|
template_source = os.path.join(working_dir, "data", "templates", template_file)
|
||||||
|
template_dest = os.path.join(temp_dir.name, "templates", template_file)
|
||||||
|
os.makedirs(os.path.dirname(template_dest), exist_ok=True)
|
||||||
|
shutil.copy2(template_source, template_dest)
|
||||||
|
return template_dest
|
||||||
|
|
||||||
|
|
||||||
@given(parse('the config "{config_file}" exists'), target_fixture="config_path")
|
@given(parse('the config "{config_file}" exists'), target_fixture="config_path")
|
||||||
def config_exists(config_file, temp_dir, working_dir):
|
def config_exists(config_file, temp_dir, working_dir):
|
||||||
config_source = os.path.join(working_dir, "data", "configs", config_file)
|
config_source = os.path.join(working_dir, "data", "configs", config_file)
|
||||||
|
|
|
@ -25,6 +25,11 @@ def should_get_no_error(cli_run):
|
||||||
assert cli_run["status"] == 0, cli_run["status"]
|
assert cli_run["status"] == 0, cli_run["status"]
|
||||||
|
|
||||||
|
|
||||||
|
@then("we should get an error")
|
||||||
|
def should_get_an_error(cli_run):
|
||||||
|
assert cli_run["status"] != 0, cli_run["status"]
|
||||||
|
|
||||||
|
|
||||||
@then(parse("the output should match\n{regex}"))
|
@then(parse("the output should match\n{regex}"))
|
||||||
@then(parse('the output should match "{regex}"'))
|
@then(parse('the output should match "{regex}"'))
|
||||||
def output_should_match(regex, cli_run):
|
def output_should_match(regex, cli_run):
|
||||||
|
|
|
@ -42,6 +42,7 @@ def expected_args(**kwargs):
|
||||||
"strict": False,
|
"strict": False,
|
||||||
"tagged": False,
|
"tagged": False,
|
||||||
"tags": False,
|
"tags": False,
|
||||||
|
"template": None,
|
||||||
"text": [],
|
"text": [],
|
||||||
"config_override": [],
|
"config_override": [],
|
||||||
"config_file_path": "",
|
"config_file_path": "",
|
||||||
|
|
Loading…
Add table
Reference in a new issue