-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
76 changed files
with
1,911 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
name: tests | ||
|
||
on: | ||
push: | ||
branches: | ||
- '*' | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
os: [ubuntu-latest, macos-latest, windows-latest] | ||
python-version: [ "pypy3.9", "pypy3.10", "3.9", "3.10", "3.11", "3.12" ] | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
|
||
- name: Display Python version | ||
run: python -c "import sys; print(sys.version)" | ||
|
||
- name: Install dependencies | ||
run: python -m pip install --upgrade pip setuptools wheel coverage ruff | ||
|
||
- name: Lint with Ruff | ||
run: | | ||
ruff --output-format=github . | ||
continue-on-error: true | ||
|
||
- name: Run tests | ||
run: | | ||
pip install -e . | ||
python -m unittest discover -s tests/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
# geny | ||
An extendable file and project generator | ||
An extendable file generator |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# coding: utf-8 | ||
""" | ||
geny: an extendable file generator | ||
""" | ||
import os | ||
|
||
__version__ = "0.1.0" | ||
__license__ = "BSD 3-Clause" | ||
__author__ = "Leo Neto" | ||
__copyright__ = "Copyright 2024 Leo Neto" | ||
|
||
COMMANDS_FOLDER = os.path.join(os.path.dirname(__file__), "commands") | ||
|
||
PLUGINS_FOLDER = os.environ.get("GENY_PLUGINS", None) | ||
|
||
VERSION = __version__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# cli |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import click | ||
import logging | ||
from pathlib import Path | ||
from geny import VERSION | ||
from geny.extensions.combined import AliasedAndDiscoverableGroup | ||
from geny.core.templates.template import TemplateParser | ||
|
||
|
||
@click.command( | ||
cls=AliasedAndDiscoverableGroup, context_settings=dict(ignore_unknown_options=True) | ||
) | ||
@click.option("--debug", is_flag=True, help="Enable debug logs.") | ||
@click.option("--dry", is_flag=True, help="Do not modify the file system.") | ||
@click.option("-f", "--force", is_flag=True, help="Override any conflicting files.") | ||
@click.option("--verbose", is_flag=True, help="Enable verbosity.") | ||
@click.option( | ||
"--templates-dir", | ||
"-t", | ||
envvar="GENY_TEMPLATES_DIR", | ||
help="Template directory.", | ||
type=click.Path(), | ||
) | ||
@click.version_option(version=VERSION) | ||
@click.pass_context | ||
def cli(ctx, debug, dry, force, verbose, templates_dir): | ||
""" | ||
geny | ||
an extendable file generator. | ||
""" | ||
|
||
# Note for contributors: | ||
# | ||
# Commands are auto-discovered if they are placed under the commands directory. | ||
# But please be sure to do the following for this to work: | ||
# 1. Name your package and click command the same. | ||
# 2. Place your command definition within your package's main.py module | ||
# 3. Any sub-commands of your command should be added to the top-most command in the package's main.py module. | ||
# | ||
# Access your command like so: | ||
# `geny my-command my-command-sub-command` | ||
# | ||
# If you would like to skip a plugin/command from being auto-discovered, | ||
# simply rename the package by either prepending or appending any number of underscores (_). | ||
# Any code contained within the package will be ignored. | ||
|
||
ctx.ensure_object(dict) | ||
|
||
from rich.logging import RichHandler | ||
|
||
FORMAT = "[DRY] %(message)s" if dry else "%(message)s" | ||
|
||
logging.basicConfig( | ||
encoding="utf-8", | ||
level=logging.DEBUG if verbose else logging.INFO, | ||
format=FORMAT, | ||
handlers=[ | ||
RichHandler( | ||
log_time_format="", | ||
show_path=False, | ||
show_level=False, | ||
enable_link_path=True, | ||
markup=True, | ||
) | ||
], | ||
) | ||
|
||
templates = [Path(__file__).resolve().parent.parent / "template_files"] | ||
|
||
if templates_dir is not None: | ||
templates.append(Path(templates_dir)) | ||
|
||
TemplateParser( | ||
templates_dir=templates, | ||
context={}, | ||
) | ||
|
||
ctx.obj["ENABLE_DEBUG"] = debug | ||
ctx.obj["ENABLE_DRY_RUN"] = dry | ||
ctx.obj["ENABLE_FORCE"] = force | ||
ctx.obj["ENABLE_VERBOSITY"] = verbose | ||
|
||
|
||
if __name__ == "__main__": | ||
try: | ||
cli() | ||
except (KeyboardInterrupt, SystemExit) as e: | ||
click.echo(f"Exited! {repr(e)}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# commands |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from geny.core.utils import sanitized_string | ||
|
||
|
||
def sanitized_string_callback(ctx, param, value): | ||
return sanitized_string(value) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import click | ||
|
||
from geny.core.filesystem.files import File | ||
|
||
|
||
@click.command() | ||
@click.option("--docker-compose", is_flag=True) | ||
@click.pass_context | ||
def dockerfile(ctx, docker_compose): | ||
""" | ||
Destroy a Dockerfile (and docker-compose.yaml). | ||
""" | ||
|
||
files = [ | ||
File(name="Dockerfile"), | ||
] | ||
|
||
if docker_compose: | ||
files.append(File(name="docker-compose.yaml")) | ||
|
||
[ | ||
file.destroy( | ||
**ctx.obj, | ||
) | ||
for file in files | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# commands:destroy | ||
import click | ||
|
||
from geny.commands.destroy.dockerfile import dockerfile | ||
from geny.commands.destroy.template import template | ||
|
||
|
||
@click.group() | ||
@click.pass_context | ||
def destroy(ctx): | ||
""" | ||
Destroy files. | ||
""" | ||
|
||
ctx.ensure_object(dict) | ||
|
||
|
||
[ | ||
destroy.add_command(cmd) | ||
for cmd in [ | ||
dockerfile, | ||
template, | ||
] | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import click | ||
|
||
from geny.commands.callbacks import sanitized_string_callback | ||
from geny.core.filesystem.files import File | ||
|
||
|
||
SUPPORTED_CLASSES = [ | ||
"create", | ||
"detail", | ||
"list", | ||
"update", | ||
] | ||
|
||
|
||
@click.command(context_settings=dict(ignore_unknown_options=True)) | ||
@click.argument("name", required=True, callback=sanitized_string_callback) | ||
@click.option("--class_", type=click.Choice(SUPPORTED_CLASSES)) | ||
@click.option("--full", is_flag=True, help="Destroy templates for all CRUD operations") | ||
@click.pass_context | ||
def template(ctx, name, class_, full): | ||
""" | ||
Destroy an html template. | ||
""" | ||
|
||
classes = SUPPORTED_CLASSES if full else [class_] | ||
|
||
for k in classes: | ||
File(name=f"templates/{name}{'_' + k if k else ''}.html").destroy(**ctx.obj) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import click | ||
|
||
from geny.core.filesystem.files import File | ||
|
||
|
||
@click.command() | ||
@click.option("--docker-compose", is_flag=True) | ||
@click.pass_context | ||
def dockerfile(ctx, docker_compose): | ||
""" | ||
Generate a Dockerfile. | ||
""" | ||
|
||
files = [ | ||
File(name="Dockerfile", template="docker/dockerfile.tpl", context={}), | ||
] | ||
|
||
if docker_compose: | ||
files.append( | ||
File( | ||
name="docker-compose.yaml", | ||
template="docker/docker-compose.tpl", | ||
context={ | ||
"services": [ | ||
"celery", | ||
"kafka", | ||
"postgres", | ||
"rabbitmq" "redis", | ||
], | ||
}, | ||
) | ||
) | ||
|
||
[ | ||
file.create( | ||
**ctx.obj, | ||
) | ||
for file in files | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# commands:generate | ||
import click | ||
|
||
from geny.commands.generate.dockerfile import dockerfile | ||
from geny.commands.generate.template import template | ||
|
||
|
||
@click.group() | ||
@click.pass_context | ||
def generate(ctx): | ||
""" | ||
Create files. | ||
""" | ||
|
||
ctx.ensure_object(dict) | ||
|
||
|
||
[ | ||
generate.add_command(cmd) | ||
for cmd in [ | ||
dockerfile, | ||
template, | ||
] | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import click | ||
import inflection | ||
|
||
from geny.commands.callbacks import sanitized_string_callback | ||
from geny.core.filesystem.files import File | ||
|
||
|
||
SUPPORTED_CLASSES = [ | ||
"create", | ||
"detail", | ||
"list", | ||
"update", | ||
] | ||
|
||
|
||
@click.command(context_settings=dict(ignore_unknown_options=True)) | ||
@click.argument("name", required=True, callback=sanitized_string_callback) | ||
@click.option("--class_", type=click.Choice(SUPPORTED_CLASSES)) | ||
@click.option("--full", is_flag=True, help="Create templates for all CRUD operations") | ||
@click.pass_context | ||
def template(ctx, name, class_, full): | ||
""" | ||
Generate an html template. | ||
""" | ||
|
||
classes = SUPPORTED_CLASSES if full else [class_] | ||
|
||
for k in classes: | ||
file = File( | ||
name=f"templates/{name}{'_' + k if k else ''}.html", | ||
template=f"templates/{k if k else 'template'}.tpl", | ||
context={ | ||
"classname": inflection.camelize(name), | ||
}, | ||
) | ||
|
||
file.create(**ctx.obj) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# core |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# core:decorators |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# core:decorators | ||
import click | ||
|
||
|
||
def halt_on_error(f): | ||
def wrapper(*args, **kwargs): | ||
try: | ||
f(*args, **kwargs) | ||
except Exception as err: | ||
click.echo(repr(err), err=True) | ||
raise click.Abort() | ||
|
||
return wrapper |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# core:decorators:singleton | ||
import functools | ||
|
||
|
||
def singleton(cls): | ||
""" | ||
Make a class a Singleton class (only one instance) | ||
Source: https://realpython.com/primer-on-python-decorators/#stateful-decorators | ||
""" | ||
|
||
@functools.wraps(cls) | ||
def wrapper_singleton(*args, **kwargs): | ||
if not wrapper_singleton.instance: | ||
wrapper_singleton.instance = cls(*args, **kwargs) | ||
return wrapper_singleton.instance | ||
|
||
wrapper_singleton.instance = None | ||
return wrapper_singleton |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# core:filesystem |
Oops, something went wrong.