Skip to content

Commit

Permalink
Add git helper functions (Fixes #4)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericof committed Apr 20, 2024
1 parent 4e45a08 commit 47cff82
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 23 deletions.
29 changes: 9 additions & 20 deletions cookieplone/cli.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
"""Main `cookieplone` CLI."""

import os
import sys
from pathlib import Path
from typing import Annotated

import typer
from cookiecutter import __version__ as __cookiecutter_version__
from cookiecutter.log import configure_logger
from rich import print
from rich.prompt import Prompt

from cookieplone import __version__, data
from cookieplone import data, settings
from cookieplone.exceptions import GeneratorException
from cookieplone.generator import generate
from cookieplone.repository import get_base_repository, get_template_options
from cookieplone.utils import console
from cookieplone.utils import console, internal


def validate_extra_context(value: list[str] | None = None):
Expand All @@ -42,17 +40,6 @@ def prompt_for_template(base_path: Path) -> str:
return choices[answer]


def version_info() -> str:
"""Return the Cookieplone version, location and Python powering it."""
python_version = sys.version
location = Path(__file__).parent
return (
f"Cookieplone {__version__} from {location} "
f"(Cookiecutter {__cookiecutter_version__}, "
f"Python {python_version})"
)


def cli(
template: Annotated[str, typer.Argument(help="Template to be used.")] = "",
extra_context: Annotated[
Expand Down Expand Up @@ -120,28 +107,30 @@ def cli(
):
"""Generate a new Plone codebase."""
if version:
info = version_info
print(info)
print(internal.version_info)
raise typer.Exit()
repository = os.environ.get("COOKIEPLONE_REPOSITORY")
repository = os.environ.get(settings.REPO_LOCATION)
if not repository:
repository = "gh:plone/cookiecutter-plone"

repo_path = get_base_repository(repository)
if not template:
# Display template options
repo_path = get_base_repository(repository)
template = prompt_for_template(Path(repo_path))
else:
console.welcome_screen()

if replay_file:
replay = replay_file
passwd = os.environ.get(
"COOKIECUTTER_REPO_PASSWORD", os.environ.get("COOKIEPLONE_REPO_PASSWORD")
settings.REPO_PASSWORD, os.environ.get("COOKIECUTTER_REPO_PASSWORD")
)
if not output_dir:
output_dir = Path().cwd()
configure_logger(stream_level="DEBUG" if verbose else "INFO", debug_file=debug_file)
# Annotate extra_context
extra_context = extra_context if extra_context else {}
extra_context["__generator_signature"] = internal.signature_md(repo_path)
# Run generator
try:
generate(
Expand Down
2 changes: 2 additions & 0 deletions cookieplone/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@

## Config
QUIET_MODE_VAR = "COOKIEPLONE_QUIET_MODE_SWITCH"
REPO_LOCATION = "COOKIEPLONE_REPOSITORY"
REPO_PASSWORD = "COOKIEPLONE_REPO_PASSWORD" # noQA:S105
14 changes: 11 additions & 3 deletions cookieplone/utils/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from textwrap import dedent

from rich import print as base_print
from rich.align import Align
from rich.console import Group
from rich.markup import escape
from rich.panel import Panel
from rich.table import Table
Expand Down Expand Up @@ -118,10 +120,16 @@ def table_available_templates(title: str, rows: list[list[str]]):


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


def enable_quiet_mode():
Expand Down
32 changes: 32 additions & 0 deletions cookieplone/utils/git.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from pathlib import Path

from git import Commit, Repo
from git.exc import InvalidGitRepositoryError


def repo_from_path(path: Path) -> Repo | None:
"""Return the repo for the given path."""
try:
repo = Repo(path)
except InvalidGitRepositoryError:
repo = None
return repo


def check_path_is_repository(path: Path) -> bool:
"""Check if given path is a Git Repository."""
return bool(repo_from_path(path))


def initialize_repository(path: Path) -> Repo:
"""Initialize a git repository and add all files."""
if not check_path_is_repository(path):
repo = Repo.init(path)
repo.git.add(path)
return repo


def get_last_commit(path: Path) -> Commit | None:
"""Return the last commit for a repo."""
repo = repo_from_path(path)
return repo.head.commit if repo else None
36 changes: 36 additions & 0 deletions cookieplone/utils/internal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import sys
from datetime import datetime
from pathlib import Path

from cookiecutter import __version__ as __cookiecutter_version__

from cookieplone import __version__
from cookieplone.utils import git

COOKIEPLONE_REPO = "https://github.com/plone/cookieplone"
TEMPLATES_REPO = "https://github.com/plone/cookiecutter-plone"


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"(Cookiecutter {__cookiecutter_version__}, "
f"Python {python_version})"
)


def signature_md(path: Path) -> str:
"""Return a signature, in markdown."""
date_info = f"{datetime.now()}"
cookieplone = f"[Cookieplone ({__version__})]({COOKIEPLONE_REPO})"
commit = git.get_last_commit(path)
if not commit:
template = f"[cookiecutter-plone]({TEMPLATES_REPO})"
else:
sha = commit.hexsha
template = f"[cookiecutter-plone ({sha[:7]})]({TEMPLATES_REPO}/commit/{sha})"
return f"""Generated using {cookieplone} and {template} on {date_info}"""

0 comments on commit 47cff82

Please sign in to comment.