From 5e613121130a640ff6721fec322a9a948cfa7a1e Mon Sep 17 00:00:00 2001 From: Corey Oordt Date: Sun, 3 Jul 2022 11:36:41 -0500 Subject: [PATCH] Added layer naming convention --- cookie_composer/composition.py | 16 ++++++++++--- cookie_composer/layers.py | 1 + cookie_composer/utils.py | 41 +++++++++++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/cookie_composer/composition.py b/cookie_composer/composition.py index 83f3c7b..9ec9eba 100644 --- a/cookie_composer/composition.py +++ b/cookie_composer/composition.py @@ -46,9 +46,7 @@ class LayerConfig(BaseModel): """Directory within a git repository template that holds the cookiecutter.json file.""" checkout: Optional[str] - """The branch, tag or commit to use if template is a git repository. - - Also used for updating projects.""" + """The branch, tag or commit to use if template is a git repository.""" password: Optional[str] """The password to use if template is a password-protected Zip archive.""" @@ -91,6 +89,13 @@ class LayerConfig(BaseModel): merge_strategies: Dict[str, str] = Field(default_factory=lambda: {"*": DO_NOT_MERGE}) """The method to merge specific paths or glob patterns.""" + @property + def layer_name(self) -> str: + """The name of the template layer.""" + from cookie_composer.utils import get_template_name + + return get_template_name(self.template, self.directory, self.checkout) + class RenderedLayer(BaseModel): """Information about a rendered layer.""" @@ -147,6 +152,11 @@ class RenderedComposition(BaseModel): rendered_name: str """The name of the rendered project.""" + @property + def layer_names(self) -> List[str]: + """Return a list of the names of all the layers.""" + return [x.layer.layer_name for x in self.layers] + def is_composition_file(path_or_url: Union[str, Path]) -> bool: """ diff --git a/cookie_composer/layers.py b/cookie_composer/layers.py index 45741e1..f3ee445 100644 --- a/cookie_composer/layers.py +++ b/cookie_composer/layers.py @@ -199,6 +199,7 @@ def render_layers( with tempfile.TemporaryDirectory() as render_dir: rendered_layer = render_layer(layer_config, render_dir, full_context, accept_hooks) merge_layers(destination, rendered_layer) + rendered_layer.location = destination rendered_layer.layer.commit = rendered_layer.latest_commit rendered_layer.layer.context = rendered_layer.new_context rendered_layers.append(rendered_layer) diff --git a/cookie_composer/utils.py b/cookie_composer/utils.py index cb8ec99..337cc20 100644 --- a/cookie_composer/utils.py +++ b/cookie_composer/utils.py @@ -1,5 +1,5 @@ """Utilities not easily categorized.""" -from typing import Optional +from typing import IO, Any, Optional from pathlib import Path @@ -32,12 +32,14 @@ def get_context_for_layer(composition: RenderedComposition, index: Optional[int] return full_context -def get_template_name(path_or_url: str) -> str: +def get_template_name(path_or_url: str, directory: Optional[str] = None, checkout: Optional[str] = None) -> str: """ Get the name of the template using the path or URL. Args: path_or_url: The URL or path to the template + directory: Directory within a git repository template that holds the cookiecutter.json file. + checkout: The branch, tag or commit to use if template is a git repository. Raises: ValueError: If the path_or_url is not parsable @@ -51,4 +53,37 @@ def get_template_name(path_or_url: str) -> str: if not path: raise ValueError("There is no path.") - return Path(path).stem + base_path = Path(path).stem + dir_name = Path(directory).name if directory else None + parts = [base_path, dir_name, checkout] + return "-".join([x for x in parts if x]) + + +def echo( + message: Optional[Any] = None, + file: Optional[IO] = None, + nl: bool = True, + err: bool = False, + color: Optional[bool] = None, + **styles +): + """ + A local abstraction for printing messages. + + Default behavior is that of ``click.secho`` . + + This is to allow user feedback without every function requiring a click dependency. + Especially during testing. + + Args: + message: The string or bytes to output. Other objects are converted to strings. + file: The file to write to. Defaults to stdout. + err: Write to stderr instead of stdout. + nl: Print a newline after the message. Enabled by default. + color: Force showing or hiding colors and other styles. By default Click will remove color if the output + does not look like an interactive terminal. + **styles: Style keyword arguments + """ + import click + + click.secho(message, file, nl, err, color, **styles)