diff --git a/CHANGES/3009.feature b/CHANGES/3009.feature new file mode 100644 index 00000000..e5403c6f --- /dev/null +++ b/CHANGES/3009.feature @@ -0,0 +1 @@ +Add command to convert markdown to html \ No newline at end of file diff --git a/README.md b/README.md index 179d4796..ff177887 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,10 @@ Supports legacy roles (note: must be in the parent directory of the legacy role) `python -m galaxy_importer.main --legacy-role [legacy_role_directory] --namespace [namespace]` +Supports converting markdown to html: + +`python -m galaxy_importer.main --markdown [readme_md_directory]` + View log output in terminal, and view the importer result in the written file `importer_result.json` #### Structure of Output diff --git a/galaxy_importer/main.py b/galaxy_importer/main.py index c46f3bad..81a6727e 100644 --- a/galaxy_importer/main.py +++ b/galaxy_importer/main.py @@ -22,7 +22,7 @@ import re import sys -from galaxy_importer import collection, legacy_role +from galaxy_importer import collection, legacy_role, markdown from galaxy_importer import config from galaxy_importer.exceptions import ImporterError @@ -97,6 +97,12 @@ def parse_args(args): parser.add_argument( "--namespace", dest="namespace", help="namespace of the legacy role to import" ) + parser.add_argument( + "--markdown", + dest="markdown", + action="store_true", + help="returns html preview of README.md", + ) return parser.parse_args(args=args) @@ -122,6 +128,17 @@ def call_importer(args, cfg): # pragma: no cover except Exception as e: logger.exception(f"Unexpected error occurred: {str(e)}") return None + elif args.markdown: + if args.file is None: + logger.error("Must supply the directory of README.md") + return None + try: + data = markdown.convert_markdown(args.file, logger=logger) + except ImporterError as e: + logger.error(f"The markdown conversion failed for the following reason: {str(e)}") + return None + except Exception as e: + logger.exception(f"Unexpected error occurred: {str(e)}") else: if not args.file: return collection.import_collection( diff --git a/galaxy_importer/markdown.py b/galaxy_importer/markdown.py new file mode 100644 index 00000000..07923f72 --- /dev/null +++ b/galaxy_importer/markdown.py @@ -0,0 +1,39 @@ +import logging +import os + +from galaxy_importer import exceptions as exc +from galaxy_importer import __version__ +from galaxy_importer.utils import markup + +default_logger = logging.getLogger(__name__) + + +def convert_markdown(dirname, logger=None): + """Convert README.md to html. + + NOTE: README.md must exist in dirname + + :param dirname: directory of role. + :param logger: Optional logger instance. + + :raises exc.ImporterError: On errors that fail the import process. + + :return: html markup of supplied README.md file + """ + logger = logger or default_logger + logger.info(f"Converting markdown with galaxy-importer {__version__}") + + # Ensure that dirname exists. + if not os.path.exists(dirname): + raise exc.ImporterError(f"Path does not exist: {dirname}") + + return _convert_markdown(dirname, logger) + + +def _convert_markdown(dirname, logger): + doc_file = markup.get_readme_doc_file(dirname) + if not doc_file: + raise exc.ImporterError(f"Path does not contain README.md: {dirname}") + else: + logger.info(f"Processing {dirname}{doc_file.name}") + return {"html": markup.get_html(doc_file)} diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index 92398e57..c82fb9de 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -58,3 +58,11 @@ def test_legacy_missing_namespace(caplog): assert data is None assert "requires explicit namespace" in caplog.text assert len(caplog.records) == 1 + + +def test_markdown_no_directory(caplog): + args = main.parse_args(["--markdown"]) + data = main.call_importer(args, None) + assert data is None + assert "Must supply the directory of README" in caplog.text + assert len(caplog.records) == 1 diff --git a/tests/unit/test_markdown.py b/tests/unit/test_markdown.py new file mode 100644 index 00000000..f0427d96 --- /dev/null +++ b/tests/unit/test_markdown.py @@ -0,0 +1,51 @@ +import logging +import os +import pytest +import tempfile + +from galaxy_importer import exceptions as exc +from galaxy_importer import markdown + +log = logging.getLogger(__name__) + +README_MD = """ +# my_readme + +Some generic readme +""" + +README_HTML = """

my_readme

+

Some generic readme

""" + + +def test_convert_markdown(mocker): + mocker.patch.object(markdown, "_convert_markdown") + with tempfile.TemporaryDirectory() as tmp_dir: + with open(os.path.join(tmp_dir, "README.md"), "w") as file: + file.write(README_MD) + markdown.convert_markdown(tmp_dir) + assert markdown._convert_markdown.called + + +def test_convert_markdown_return(): + with tempfile.TemporaryDirectory() as tmp_dir: + with open(os.path.join(tmp_dir, "README.md"), "w") as file: + file.write(README_MD) + data = markdown.convert_markdown(tmp_dir) + assert isinstance(data, dict) + assert "html" in data + assert README_HTML == data["html"] + + +def test_convert_markdown_dir_dne(): + with tempfile.TemporaryDirectory() as tmp_dir: + with pytest.raises(exc.ImporterError, match="does not exist"): + markdown.convert_markdown(f"{tmp_dir}/does/not/exist") + + +def test_convert_markdown_readme_dne(): + with tempfile.TemporaryDirectory() as tmp_dir: + with open(os.path.join(tmp_dir, "README.html"), "w") as file: + file.write(README_MD) + with pytest.raises(exc.ImporterError, match="Path does not contain README"): + markdown.convert_markdown(tmp_dir)