Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --info option to display current settings #28

Merged
merged 1 commit into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions cookieplone/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ def cli(
typer.Option("--output-dir", "-o", help="Where to generate the code."),
] = None,
tag: Annotated[str, typer.Option(help="Tag.")] = "main",
info: Annotated[
bool,
typer.Option(
"--info", help="Display information about cookieplone installation."
),
] = False,
version: Annotated[
bool, typer.Option("--version", help="Display the version of cookieplone.")
] = False,
Expand Down Expand Up @@ -114,13 +120,22 @@ def cli(
):
"""Generate a new Plone codebase."""
if version:
console.base_print(internal.version_info())
console.version_screen()
raise typer.Exit()

configure_logger(stream_level="DEBUG" if verbose else "INFO", debug_file=debug_file)
repository = os.environ.get(settings.REPO_LOCATION)
if not repository:
repository = "gh:plone/cookieplone-templates"
repository = settings.REPO_DEFAULT

passwd = os.environ.get(
settings.REPO_PASSWORD, os.environ.get("COOKIECUTTER_REPO_PASSWORD")
)
tag = os.environ.get(settings.REPO_TAG) or tag

if info:
console.info_screen(repository=repository, passwd=passwd, tag=tag)
raise typer.Exit()

repo_path = get_base_repository(repository)
if not template:
Expand All @@ -129,9 +144,6 @@ def cli(
else:
console.welcome_screen()

passwd = os.environ.get(
settings.REPO_PASSWORD, os.environ.get("COOKIECUTTER_REPO_PASSWORD")
)
if not output_dir:
output_dir = Path().cwd()

Expand Down
5 changes: 5 additions & 0 deletions cookieplone/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,13 @@
}
MIN_DOCKER_VERSION = "20.10"

## DEFAULT
COOKIEPLONE_REPO = "https://github.com/plone/cookieplone"
TEMPLATES_REPO = "https://github.com/plone/cookiecutter-plone"
REPO_DEFAULT = "gh:plone/cookieplone-templates"

## Config
QUIET_MODE_VAR = "COOKIEPLONE_QUIET_MODE_SWITCH"
REPO_LOCATION = "COOKIEPLONE_REPOSITORY"
REPO_TAG = "COOKIEPLONE_REPOSITORY_TAG"
REPO_PASSWORD = "COOKIEPLONE_REPO_PASSWORD" # noQA:S105
71 changes: 60 additions & 11 deletions cookieplone/utils/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#
# SPDX-License-Identifier: MIT
import os
from pathlib import Path
from textwrap import dedent

from rich import print as base_print
Expand All @@ -13,6 +14,8 @@

from cookieplone.settings import QUIET_MODE_VAR

from .internal import cookieplone_info, version_info

BANNER = """
.xxxxxxxxxxxxxx.
;xxxxxxxxxxxxxxxxxxxxxx;
Expand Down Expand Up @@ -108,33 +111,79 @@ def panel(title: str, msg: str = "", subtitle: str = "", url: str = ""):
)


def table_available_templates(title: str, rows: list[list[str]]):
"""Display a table of options."""
table = Table(title=title, expand=True)

table.add_column("#", justify="center", style="cyan", no_wrap=True)
table.add_column("Title", style="blue")
table.add_column("Description", justify="left", style="blue")
def create_table(
columns: list[dict] | None = None, rows: list[list[str]] | None = None, **kwargs
) -> Table:
"""Create table."""
table = Table(**kwargs)
for column in columns:
col_title = column.pop("title", "")
table.add_column(col_title, **column)
for row in rows:
table.add_row(*row)
return table

for idx, _, title, description in rows:
table.add_row(idx, title, description)

return table
def table_available_templates(title: str, rows: list[list[str]]) -> Table:
"""Display a table of options."""
columns = [
{"title": "#", "justify": "center", "style": "cyan", "no_wrap": True},
{"title": "Title", "style": "blue"},
{"title": "Description", "justify": "left", "style": "blue"},
]
rows = [(idx, title, description) for idx, _, title, description in rows]
return create_table(columns, rows, title=title, expand=True)


def welcome_screen(templates: list[list[str]] | None = None):
items = [
Align.center(f"[bold blue]{BANNER}[/bold blue]"),
]
if templates:
items.append(Panel(table_available_templates("Templates", templates)))
items.append(Panel(table_available_templates(templates, title="Templates")))
panel = Panel(
Group(*items),
title="cookieplone",
)
base_print(panel)


def version_screen():
"""Print version information."""
base_print(version_info())


def info_screen(repository: str | Path, passwd: str, tag: str):
info = cookieplone_info(repository, passwd, tag)
title = info["title"]
subtitle = info["subtitle"]
panels = info["panels"]
columns = [
{"title": "", "justify": "left", "style": "cyan", "no_wrap": True, "ratio": 1},
{"title": "", "justify": "left", "style": "cyan", "no_wrap": True, "ratio": 3},
]
items = []
for panel in panels.values():
panel_title = panel.get("title")
panel_rows = panel.get("rows")
if panel_rows:
items.append(
Panel(
create_table(
columns, panel_rows, expand=True, box=None, show_header=False
),
title=panel_title,
title_align="left",
)
)
panel = Panel(
Group(*items),
title=title,
subtitle=subtitle,
)
base_print(panel)


def enable_quiet_mode():
"""Enable quiet mode."""
os.environ[QUIET_MODE_VAR] = "1"
Expand Down
73 changes: 63 additions & 10 deletions cookieplone/utils/internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,88 @@

from cookiecutter import __version__ as __cookiecutter_version__

from cookieplone import __version__
from cookieplone import __version__, settings
from cookieplone.utils import git

COOKIEPLONE_REPO = "https://github.com/plone/cookieplone"
TEMPLATES_REPO = "https://github.com/plone/cookiecutter-plone"
SIGNATURE = (
"Made with [bold][red]❤️[/red][/bold] by the"
" [bold][blue]Plone Community[/blue][/bold]"
)


def __cookiecutter_location__() -> Path:
"""Return the cookiecutter location."""
import cookiecutter

return Path(cookiecutter.__file__).parent


def __location__() -> Path:
"""Return the cookieplone location."""
return Path(__file__).parent.parent


def version_info() -> str:
"""Return the Cookieplone version, location and Python powering it."""
python_version = sys.version
# Get the root of cookieplone
location = Path(__file__).parent.parent
return (
f"Cookieplone {__version__} from {location} "
f"Cookieplone {__version__} from {__location__()} "
f"(Cookiecutter {__cookiecutter_version__}, "
f"Python {python_version})\n\n"
f"Made with [bold][red]❤️[/red][/bold] by the"
" [bold][blue]Plone Community[/blue][/bold]"
f"{SIGNATURE}"
)


def cookieplone_info(repository: str | Path, passwd: str = "", tag: str = "") -> dict:
"""Print information about current configuration."""
return {
"title": "cookieplone",
"subtitle": SIGNATURE,
"panels": {
"cookieplone": {
"title": "Installation :zap:",
"rows": [
["Version", __version__],
["Location", f"{__location__()}"],
],
},
"repository": {
"title": "Repository :link:",
"rows": [
[f"Location ({settings.REPO_LOCATION})", f"{repository}"],
[f"Tag ({settings.REPO_TAG})", tag],
[f"Password ({settings.REPO_PASSWORD})", "***" if passwd else ""],
],
},
"cookiecutter": {
"title": "Cookiecutter :cookie:",
"rows": [
["Version", __cookiecutter_version__],
["Location", f"{__cookiecutter_location__()}"],
],
},
"python": {
"title": "Python :snake:",
"rows": [
["Version", f"{sys.version}"],
],
},
},
}


def signature_md(path: Path) -> str:
"""Return a signature, in markdown."""
date_info = f"{datetime.now()}"
cookieplone = f"[Cookieplone ({__version__})]({COOKIEPLONE_REPO})"
cookieplone = f"[Cookieplone ({__version__})]({settings.COOKIEPLONE_REPO})"
commit = git.get_last_commit(path)
template_title = "cookiecutter-plone"
if not commit:
template = f"[cookiecutter-plone]({TEMPLATES_REPO})"
template_link = settings.TEMPLATES_REPO
else:
sha = commit.hexsha
template = f"[cookiecutter-plone ({sha[:7]})]({TEMPLATES_REPO}/commit/{sha})"
template_title = f"{template_title} ({sha[:7]})"
template_link = f"{settings.TEMPLATES_REPO}/commit/{sha}"
template = f"[{template_title}]({template_link})"
return f"""Generated using {cookieplone} and {template} on {date_info}"""
1 change: 1 addition & 0 deletions news/27.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add --info option to display current settings [@ericof]
24 changes: 23 additions & 1 deletion tests/utils/test_internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
import sys
from pathlib import Path

import pytest
from cookiecutter import __version__ as __cookiecutter_version__

from cookieplone import __version__
from cookieplone import __version__, settings
from cookieplone.utils import internal


Expand All @@ -20,6 +21,27 @@ def test_version_info():
assert entry in result


@pytest.mark.parametrize(
"panel_id,panel_title",
[
["cookieplone", "Installation :zap:"],
["repository", "Repository :link:"],
["cookiecutter", "Cookiecutter :cookie:"],
["python", "Python :snake:"],
],
)
def test_cookieplone_info(panel_id: str, panel_title: str):
result = internal.cookieplone_info(settings.REPO_DEFAULT)
assert isinstance(result, dict)
assert result["title"] == "cookieplone"
assert result["subtitle"] == internal.SIGNATURE
panels = result["panels"]
assert isinstance(panels, dict)
panel = panels[panel_id]
assert isinstance(panel, dict)
assert panel["title"] == panel_title


def test_signature_md_without_commit(no_repo):
result = internal.signature_md(no_repo)
assert isinstance(result, str)
Expand Down