mirror of
https://github.com/dtomlinson91/tembo.git
synced 2025-12-22 07:55:45 +00:00
adding latest
This commit is contained in:
@@ -25,6 +25,7 @@ Documentation:
|
|||||||
<https://stackoverflow.com/questions/53125305/testing-logging-output-with-pytest>
|
<https://stackoverflow.com/questions/53125305/testing-logging-output-with-pytest>
|
||||||
|
|
||||||
☐ Document using datadir with a module rather than a shared one. Link to tembo as an example.
|
☐ Document using datadir with a module rather than a shared one. Link to tembo as an example.
|
||||||
|
☐ Can prospector ignore tests dir? document this in the gist if so
|
||||||
|
|
||||||
Functionality:
|
Functionality:
|
||||||
✔ Move any `tembo.CONFIG` calls out of `pages.py` and ensure these are passed in from the cli. @done(21-10-28 19:44)
|
✔ Move any `tembo.CONFIG` calls out of `pages.py` and ensure these are passed in from the cli. @done(21-10-28 19:44)
|
||||||
@@ -32,9 +33,9 @@ Functionality:
|
|||||||
✔ Make example optional @done(21-10-29 00:15)
|
✔ Make example optional @done(21-10-29 00:15)
|
||||||
✔ Add the `--example` output to the miscounted token message so the user knows the correct command to use. @done(21-10-29 00:15)
|
✔ Add the `--example` output to the miscounted token message so the user knows the correct command to use. @done(21-10-29 00:15)
|
||||||
✔ Page options dataclass @done(21-10-28 20:09)
|
✔ Page options dataclass @done(21-10-28 20:09)
|
||||||
|
☐ Make user_input optional @important
|
||||||
☐ Replace loggers with `click.echo` for command outputs. Keep logging messages for actual logging messages?
|
☐ Replace loggers with `click.echo` for command outputs. Keep logging messages for actual logging messages?
|
||||||
☐ Look at `_convert_to_path()` and see if it can be rewritten to make it clearer when there isn't a base path.
|
✔ Look at `_convert_to_path()` and see if it can be rewritten to make it clearer when there isn't a base path. @done(21-10-30 02:14)
|
||||||
Currently checks to see if base_path is not None but this is never the case as a string must be passed in and if there isn't a base_path we pass in an empty string.
|
|
||||||
☐ Replace scoped page creator inputs so that the whole class uses the options dict rather than the variables passed around.
|
☐ Replace scoped page creator inputs so that the whole class uses the options dict rather than the variables passed around.
|
||||||
☐ Use the python runner Duty
|
☐ Use the python runner Duty
|
||||||
<https://github.com/pawamoy/duty>
|
<https://github.com/pawamoy/duty>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ optional:
|
|||||||
- template_path
|
- template_path
|
||||||
- example
|
- example
|
||||||
- template_filename
|
- template_filename
|
||||||
|
- user_input
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- base_path
|
- base_path
|
||||||
@@ -11,20 +12,15 @@ required:
|
|||||||
- filename
|
- filename
|
||||||
- extension
|
- extension
|
||||||
- name
|
- name
|
||||||
- user_input - should be optional
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- page with a template
|
|
||||||
- page without a template
|
|
||||||
- page using date tokens
|
|
||||||
- page using input tokens
|
|
||||||
- page using name tokens
|
|
||||||
|
|
||||||
|
|
||||||
|
- page using/not using input tokens
|
||||||
|
- page with/without a template
|
||||||
- user input does not match number of input tokens
|
- user input does not match number of input tokens
|
||||||
|
- user input is None
|
||||||
|
- the given base path does not exist
|
||||||
|
- page using/not using date tokens
|
||||||
|
- page using/not using name tokens
|
||||||
|
|
||||||
|
|
||||||
|
- path/page filenames can contain spaces and they are converted
|
||||||
|
|
||||||
- user input does match number of input tokensE
|
|
||||||
|
|||||||
@@ -13,14 +13,29 @@ from jinja2.exceptions import TemplateNotFound
|
|||||||
import tembo
|
import tembo
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: flesh this out with details for the optional args
|
||||||
@dataclass
|
@dataclass
|
||||||
class PageCreatorOptions:
|
class PageCreatorOptions:
|
||||||
|
"""Options dataclass to create a Page.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
base_path (str):
|
||||||
|
page_path (str):
|
||||||
|
filename (str):
|
||||||
|
extension (str):
|
||||||
|
name (str):
|
||||||
|
user_input (Collection[str] | None, optional):
|
||||||
|
example (str | None, optional):
|
||||||
|
template_filename (str | None, optional):
|
||||||
|
template_path (str | None, optional):
|
||||||
|
"""
|
||||||
|
|
||||||
base_path: str
|
base_path: str
|
||||||
page_path: str
|
page_path: str
|
||||||
filename: str
|
filename: str
|
||||||
extension: str
|
extension: str
|
||||||
name: str
|
name: str
|
||||||
user_input: Collection[str]
|
user_input: Collection[str] | None = None
|
||||||
example: str | None = None
|
example: str | None = None
|
||||||
template_filename: str | None = None
|
template_filename: str | None = None
|
||||||
template_path: str | None = None
|
template_path: str | None = None
|
||||||
@@ -92,51 +107,48 @@ class ScopedPageCreator(PageCreator):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.base_path = ""
|
# self.base_path = ""
|
||||||
self.page_path = ""
|
# self.page_path = ""
|
||||||
self.filename = ""
|
# self.filename = ""
|
||||||
self.extension = ""
|
# self.extension = ""
|
||||||
self._all_input_tokens: list[str] = []
|
self._all_input_tokens: list[str] = []
|
||||||
|
self.options: PageCreatorOptions
|
||||||
|
|
||||||
def create_page(self, options: PageCreatorOptions) -> Page:
|
def create_page(self, options: PageCreatorOptions) -> Page:
|
||||||
self.base_path = options.base_path
|
self.options = options
|
||||||
self.page_path = options.page_path
|
|
||||||
self.filename = options.filename
|
|
||||||
self.extension = options.extension
|
|
||||||
|
|
||||||
# verify the user input length matches the number of input tokens in the
|
|
||||||
# tembo config/templates
|
|
||||||
self._all_input_tokens = self._get_input_tokens(
|
self._all_input_tokens = self._get_input_tokens(
|
||||||
options.template_filename, options.template_path
|
options.template_filename, options.template_path
|
||||||
)
|
)
|
||||||
self._verify_input_tokens(options.user_input, options.example)
|
self._verify_input_tokens(options.user_input, options.example)
|
||||||
|
|
||||||
# get the path of the scoped page
|
|
||||||
path = self._convert_to_path(
|
path = self._convert_to_path(
|
||||||
self.base_path, self.page_path, self.filename, self.extension
|
self.options.base_path,
|
||||||
|
self.options.page_path,
|
||||||
|
self.options.filename,
|
||||||
|
self.options.extension,
|
||||||
)
|
)
|
||||||
|
|
||||||
# substitute tokens in the filepath
|
|
||||||
path = pathlib.Path(
|
path = pathlib.Path(
|
||||||
self._substitute_tokens(str(path), options.user_input, options.name)
|
self._substitute_tokens(str(path), options.user_input, options.name)
|
||||||
)
|
)
|
||||||
|
|
||||||
# get the template file
|
|
||||||
template_contents = self._get_template_contents(
|
template_contents = self._get_template_contents(
|
||||||
options.template_filename, options.template_path
|
options.template_filename, options.template_path
|
||||||
)
|
)
|
||||||
# substitute tokens in template_contents
|
|
||||||
if options.template_filename is not None:
|
if options.template_filename is not None:
|
||||||
template_contents = self._substitute_tokens(
|
template_contents = self._substitute_tokens(
|
||||||
template_contents, options.user_input, options.name
|
template_contents, options.user_input, options.name
|
||||||
)
|
)
|
||||||
|
|
||||||
return ScopedPage(path, template_contents)
|
return ScopedPage(path, template_contents)
|
||||||
|
|
||||||
def _get_template_contents(
|
def _get_template_contents(
|
||||||
self, template_filename: str | None, template_path: str | None
|
self, template_filename: str | None, template_path: str | None
|
||||||
) -> str:
|
) -> str:
|
||||||
return (
|
return (
|
||||||
self._load_template(self.base_path, template_filename, template_path)
|
self._load_template(
|
||||||
|
self.options.base_path, template_filename, template_path
|
||||||
|
)
|
||||||
if template_filename is not None
|
if template_filename is not None
|
||||||
else ""
|
else ""
|
||||||
)
|
)
|
||||||
@@ -146,7 +158,10 @@ class ScopedPageCreator(PageCreator):
|
|||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
path = str(
|
path = str(
|
||||||
pathlib.Path(
|
pathlib.Path(
|
||||||
self.base_path, self.page_path, self.filename, self.extension
|
self.options.base_path,
|
||||||
|
self.options.page_path,
|
||||||
|
self.options.filename,
|
||||||
|
self.options.extension,
|
||||||
).expanduser()
|
).expanduser()
|
||||||
)
|
)
|
||||||
template_contents = self._get_template_contents(
|
template_contents = self._get_template_contents(
|
||||||
@@ -159,8 +174,23 @@ class ScopedPageCreator(PageCreator):
|
|||||||
return sorted(all_input_tokens)
|
return sorted(all_input_tokens)
|
||||||
|
|
||||||
def _verify_input_tokens(
|
def _verify_input_tokens(
|
||||||
self, user_input: Collection[str], example: str | None
|
self, user_input: Collection[str] | None, example: str | None
|
||||||
) -> None:
|
) -> None:
|
||||||
|
if len(self._all_input_tokens) > 0 and user_input is None:
|
||||||
|
if example is not None:
|
||||||
|
tembo.logger.critical(
|
||||||
|
"Your tembo.config/template specifies %s input tokens, you gave 0. Example command: %s",
|
||||||
|
len(self._all_input_tokens),
|
||||||
|
example,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
tembo.logger.critical(
|
||||||
|
"Your tembo.config/template specifies %s input tokens, you gave 0.",
|
||||||
|
len(self._all_input_tokens),
|
||||||
|
)
|
||||||
|
raise SystemExit(1)
|
||||||
|
if user_input is None:
|
||||||
|
return
|
||||||
if len(self._all_input_tokens) != len(user_input):
|
if len(self._all_input_tokens) != len(user_input):
|
||||||
if example is not None:
|
if example is not None:
|
||||||
tembo.logger.critical(
|
tembo.logger.critical(
|
||||||
@@ -176,11 +206,12 @@ class ScopedPageCreator(PageCreator):
|
|||||||
len(user_input),
|
len(user_input),
|
||||||
)
|
)
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
|
return
|
||||||
|
|
||||||
def _substitute_tokens(
|
def _substitute_tokens(
|
||||||
self,
|
self,
|
||||||
tokenified_string: str,
|
tokenified_string: str,
|
||||||
user_input: Collection[str],
|
user_input: Collection[str] | None,
|
||||||
name: str,
|
name: str,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""For a tokened string, substitute input, name and date tokens."""
|
"""For a tokened string, substitute input, name and date tokens."""
|
||||||
@@ -194,13 +225,13 @@ class ScopedPageCreator(PageCreator):
|
|||||||
def __substitute_input_tokens(
|
def __substitute_input_tokens(
|
||||||
self,
|
self,
|
||||||
tokenified_string: str,
|
tokenified_string: str,
|
||||||
user_input: Collection[str],
|
user_input: Collection[str] | None,
|
||||||
) -> str:
|
) -> str:
|
||||||
for input_value, extracted_token in zip(user_input, self._all_input_tokens):
|
if user_input is not None:
|
||||||
# REVIEW: test this for spaces in the filename/input token
|
for input_value, extracted_token in zip(user_input, self._all_input_tokens):
|
||||||
tokenified_string = tokenified_string.replace(
|
tokenified_string = tokenified_string.replace(
|
||||||
extracted_token, input_value.replace(" ", "_")
|
extracted_token, input_value.replace(" ", "_")
|
||||||
)
|
)
|
||||||
return tokenified_string
|
return tokenified_string
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
Reference in New Issue
Block a user