jrnl/features/environment.py
MinchinWeb 1a7e8d8ea2
Use implicit namespace plugins for import and export (#1216)
* behavior outline

* FIrst pass at allow external plugins

* remove template exporter

* Add listing of active plugins to '--version' output

* Documentation for plugins

* [Docs] add custom imports and exporters to site TOC

* [Docs] better linewrapping

* enforce positive initial linewrap

Check column widths

update gitignore

throw error when linewrap too small

simply check for large enough linewrap value

* delete unused error message

* PR feedback

make exception more informative

update check_linewrap signature in src and test

make check_linewrap a free function

* delete unused function

* delete else..pass block

* newline for make format

* Include dates_exporter

* Use Base classes for importer and exporters.

* [Docs] improve documentation of custom Importers and Exporters

* [Testing] separate run with external plugin!

* basic behavior test

* prototype unittest for JSON Exporter

test for unimplemented method

* make format

delete unused imports

* Remove 'importer' or 'exporter' from filenames where not needed

* [Test] run different tests with or without the external plugins installed

* [Test] move test rot13 plugin into git tree

from 0dc912af82

* consolidate demo plugins to common package

* [Docs] name page for plugins

* [Docs] include the sample plug in code files directly

* style fixes

* [test] determine whether to run external plug in tests based on installed packages

* improved code documentation

* style fixes for GitHub actions

* Convert "short" and "pretty" (and "default") formaters to plugins

further to https://github.com/jrnl-org/jrnl/pull/1177

* more code clean up

tests pass locally...now for GitHub...

* [tests] dynamically determine jrnl version for plugin tests

* [GitHub Actions] direct install of testing plugins

* Remove template code

* [plugins] meta --> collector

* [Docs] create scripted entries using an custom importer

* (closer to) being able to run behave tests outside project root directory

* We already know when exporter to use
Don't re-calculate it!

* [Tests] don't name test plugin 'testing"
If so named, pip won't install it.

* [Test] run behave tests with test plugins outside project root

* [Test] behave tests pass locally

* [Docs] fix typo

* [GitHub Actions] run test commands from poetry's shell

* black-ify code

* [GitHub Actions] move downstream (rather than up) to run tests

* [GitHub Actions] set shell to poetry

* [GitHub Workflows] Manually activate virtual environment

* [GitHub Actions] Skip Windows & Python 3.8
Can't seem to find Python exe?

* [GiotHub Actions] explicitly use virtual env

* [GitHub Actions] create virutal env directly

* [GitHub Actions] better activate of Windows virtual env

* [GitHub Actions] create virtual env on Mac

* [Github Actions] install wheel and upgrade pip

* [GitHub Actions] skip virtual environments altogether

* [GitHub Actions] change directory for behave test

* Remove Windows exclusions from CI as per note -- they should be working now

Co-authored-by: Suhas <sugas182@gmail.com>
Co-authored-by: Micah Jerome Ellison <micah.jerome.ellison@gmail.com>
2021-05-29 17:21:45 -07:00

115 lines
3.5 KiB
Python

import os
from pathlib import Path
import shutil
from jrnl.os_compat import on_windows
try:
from jrnl.contrib.exporter import flag as testing_exporter
except ImportError:
testing_exporter = None
CWD = os.getcwd()
HERE = Path(__file__).resolve().parent
TARGET_CWD = HERE.parent # project root folder
# @see https://behave.readthedocs.io/en/latest/tutorial.html#debug-on-error-in-case-of-step-failures
BEHAVE_DEBUG_ON_ERROR = False
def setup_debug_on_error(userdata):
global BEHAVE_DEBUG_ON_ERROR
BEHAVE_DEBUG_ON_ERROR = userdata.getbool("BEHAVE_DEBUG_ON_ERROR")
def before_all(context):
# always start in project root directory
os.chdir(TARGET_CWD)
setup_debug_on_error(context.config.userdata)
# def after_step(context, step):
# if BEHAVE_DEBUG_ON_ERROR and step.status == "failed":
# -- ENTER DEBUGGER: Zoom in on failure location.
# NOTE: Use IPython debugger, same for pdb (basic python debugger).
# import ipdb
# ipdb.post_mortem(step.exc_traceback)
def clean_all_working_dirs():
if os.path.exists(HERE / "test.txt"):
os.remove(HERE / "test.txt")
for folder in ("configs", "journals", "cache"):
working_dir = HERE / folder
if os.path.exists(working_dir):
shutil.rmtree(working_dir)
def before_feature(context, feature):
# add "skip" tag
# https://stackoverflow.com/a/42721605/4276230
if "skip" in feature.tags:
feature.skip()
return
if "skip_win" in feature.tags and on_windows():
feature.skip("Skipping on Windows")
return
if "skip_only_with_external_plugins" in feature.tags and testing_exporter is None:
feature.skip("Requires test external plugins installed")
return
if "skip_no_external_plugins" in feature.tags and testing_exporter:
feature.skip("Skipping with external plugins installed")
return
def before_scenario(context, scenario):
"""Before each scenario, backup all config and journal test data."""
# Clean up in case something went wrong
clean_all_working_dirs()
for folder in ("configs", "journals"):
original = HERE / "data" / folder
working_dir = HERE / folder
if not os.path.exists(working_dir):
os.mkdir(working_dir)
for filename in os.listdir(original):
source = original / filename
if os.path.isdir(source):
shutil.copytree(source, (working_dir / filename))
else:
shutil.copy2(source, working_dir)
# add "skip" tag
# https://stackoverflow.com/a/42721605/4276230
if "skip" in scenario.effective_tags:
scenario.skip()
return
if "skip_win" in scenario.effective_tags and on_windows():
scenario.skip("Skipping on Windows")
return
if (
"skip_only_with_external_plugins" in scenario.effective_tags
and testing_exporter is None
):
scenario.skip("Requires test external plugins installed")
return
if "skip_no_external_plugins" in scenario.effective_tags and testing_exporter:
scenario.skip("Skipping with external plugins installed")
return
def after_scenario(context, scenario):
"""After each scenario, restore all test data and remove working_dirs."""
if os.getcwd() != TARGET_CWD:
os.chdir(TARGET_CWD)
# only clean up if debugging is off and the scenario passed
if BEHAVE_DEBUG_ON_ERROR and scenario.status != "failed":
clean_all_working_dirs()
else:
clean_all_working_dirs()