Skip to content
This repository has been archived by the owner on Feb 4, 2021. It is now read-only.

Commit

Permalink
render option
Browse files Browse the repository at this point in the history
  • Loading branch information
jpsca committed Oct 23, 2019
1 parent a4107dd commit 3f7ee32
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 41 deletions.
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ copy('gl:jpscaletti/hecto.git', 'path/to/destination')
## How it works

The content of the files inside the project template are copied to the destination
without changes, **unless are suffixed with the extension '.tmpl'.**
In that case, the templating engine will be used to render them.
without changes, **unless are suffixed with the extension '.tmpl'.** (you can change
that with the `render` setting). In that case, the templating engine is used to
render them.

A slightly customized Jinja2 templating is used. The main difference is
A slightly customized Jinja2 templates are used. The main difference is
that variables are referenced with ``[[ name ]]`` instead of
``{{ name }}`` and blocks are ``[% if name %]`` instead of
``{% if name %}``. To read more about templating see the [Jinja2
Expand All @@ -60,8 +61,9 @@ hecto.copy(

data=DEFAULT_DATA,
*,
exclude=DEFAULT_FILTER,
include=DEFAULT_INCLUDE,
render=DEFAULT_RENDER,
exclude=DEFAULT_EXCLUDE,
include=[],
skip_if_exists=[],
envops={},

Expand All @@ -85,6 +87,10 @@ Uses the template in `src_path` to generate a new project at `dst_path`.
- **data** (dict):<br>
Optional. Data to be passed to the templates.

- **render** (list of str):<br>
A list of names or shell-style patterns matching files that must be rendered
with Jinja. `["*.tmpl"]` by default.

- **exclude** (list of str):<br>
Optional. A list of names or shell-style patterns matching files or folders
that must not be copied.
Expand Down Expand Up @@ -120,6 +126,10 @@ If a YAML file named `hecto.yaml` is found in the root of the project, it will b
Note that they become just _the defaults_, so any explicitly-passed argument will overwrite them.

```yaml
# Shell-style patterns files/folders that must be rendered.
render:
- "*.tmpl"

# Shell-style patterns files/folders that must not be copied.
exclude:
- "*.bar"
Expand Down
87 changes: 53 additions & 34 deletions hecto/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
__all__ = ("copy", "copy_local")

GLOBAL_DEFAULTS = {
"render": ["*.tmpl"],
"exclude": [
"~*",
"*.py[co]",
Expand All @@ -44,6 +45,7 @@ def copy(
dst_path,
data=None,
*,
render=None,
exclude=None,
include=None,
skip_if_exists=None,
Expand All @@ -68,6 +70,10 @@ def copy(
Optional. Data to be passed to the templates in addtion to the user data from
a `hecto.json`.
- render (list):
A list of names or shell-style patterns matching files that must be rendered
with Jinja. `["*.tmpl"]` by default.
- exclude (list):
A list of names or shell-style patterns matching files or folders
that must not be copied.
Expand Down Expand Up @@ -110,6 +116,7 @@ def copy(
src_path,
dst_path,
data=_data,
render=render,
exclude=exclude,
include=include,
skip_if_exists=skip_if_exists,
Expand Down Expand Up @@ -143,6 +150,7 @@ def copy_local(
dst_path,
data,
*,
render=None,
exclude=None,
include=None,
skip_if_exists=None,
Expand All @@ -152,7 +160,13 @@ def copy_local(
src_path = resolve_source_path(src_path)
dst_path = Path(dst_path).resolve()

config = get_config(src_path, exclude, include, skip_if_exists, flags)
user_settings = {
"render": render,
"exclude": exclude,
"include": include,
"skip_if_exists": skip_if_exists,
}
config = get_config(user_settings, src_path, flags)
config["exclude"].extend(["hecto.yaml", "hecto.yml"])

envops = envops or {}
Expand All @@ -161,23 +175,27 @@ def copy_local(
envops.setdefault("variable_start_string", "[[")
envops.setdefault("variable_end_string", "]]")
data.setdefault("folder_name", dst_path.name)
render = JinjaRender(src_path, data, envops)

exclude_ = [render.string(pattern) for pattern in config["exclude"]]
include_ = [render.string(pattern) for pattern in config["include"]]
skip_if_exists_ = [render.string(pattern) for pattern in config["skip_if_exists"]]

must_exclude = make_matcher(exclude_)
must_include = make_matcher(include_)
jrender = JinjaRender(src_path, data, envops)

render_patterns = [jrender.string(pattern) for pattern in config["render"]]
exclude_patterns = [jrender.string(pattern) for pattern in config["exclude"]]
include_patterns = [jrender.string(pattern) for pattern in config["include"]]
skip_if_exists_patterns = [
jrender.string(pattern) for pattern in config["skip_if_exists"]
]

must_render = make_matcher(render_patterns)
must_exclude = make_matcher(exclude_patterns)
must_include = make_matcher(include_patterns)
must_filter = make_filter(must_exclude, must_include)
must_skip = make_matcher(skip_if_exists_)
must_skip_if_exists = make_matcher(skip_if_exists_patterns)

if not flags["quiet"]:
print("") # padding space

for folder, _, files in os.walk(str(src_path)):
rel_folder = folder.replace(str(src_path), "", 1).lstrip(os.path.sep)
rel_folder = render.string(rel_folder)
rel_folder = jrender.string(rel_folder)
rel_folder = rel_folder.replace("." + os.path.sep, ".", 1)

if must_filter(rel_folder):
Expand All @@ -188,40 +206,39 @@ def copy_local(

render_folder(dst_path, rel_folder, flags)

source_paths = get_source_paths(folder, rel_folder, files, render, must_filter)
source_paths = get_source_paths(folder, rel_folder, files, jrender, must_filter)

for source_path, rel_path in source_paths:
render_file(dst_path, rel_path, source_path, render, must_skip, flags)


def get_config(src_path, exclude, include, skip_if_exists, flags):
render_file(
dst_path,
rel_path,
source_path,
jrender,
must_render,
must_skip_if_exists,
flags,
)


def get_config(user_settings, src_path, flags):
try:
return load_config(
GLOBAL_DEFAULTS,
{
"exclude": exclude,
"include": include,
"skip_if_exists": skip_if_exists,
},
[
src_path / "hecto.yaml",
src_path / "hecto.yml",
],
user_settings,
[src_path / "hecto.yaml", src_path / "hecto.yml"],
)
except yaml.YAMLError:
printf_exception(
"INVALID CONFIG FILE",
msg="hecto.yaml",
quiet=flags.get("quiet")
"INVALID CONFIG FILE", msg="hecto.yaml", quiet=flags.get("quiet")
)
return GLOBAL_DEFAULTS


def get_source_paths(folder, rel_folder, files, render, must_filter):
def get_source_paths(folder, rel_folder, files, jrender, must_filter):
source_paths = []
for src_name in files:
dst_name = re.sub(RE_TMPL, "", src_name)
dst_name = render.string(dst_name)
dst_name = jrender.string(dst_name)
rel_path = rel_folder / dst_name

if must_filter(rel_path):
Expand All @@ -246,11 +263,13 @@ def render_folder(dst_path, rel_folder, flags):
printf("create", display_path, style=Style.OK, quiet=flags["quiet"])


def render_file(dst_path, rel_path, source_path, render, must_skip, flags):
def render_file(
dst_path, rel_path, source_path, jrender, must_render, must_skip_if_exists, flags
):
"""Process or copy a file of the skeleton.
"""
if source_path.suffix == ".tmpl":
content = render(source_path)
if must_render(source_path):
content = jrender(source_path)
else:
content = None

Expand All @@ -262,7 +281,7 @@ def render_file(dst_path, rel_path, source_path, render, must_skip, flags):
printf("identical", display_path, style=Style.IGNORE, quiet=flags["quiet"])
return

if must_skip(rel_path):
if must_skip_if_exists(rel_path):
printf("skip", display_path, style=Style.WARNING, quiet=flags["quiet"])
return

Expand Down
2 changes: 1 addition & 1 deletion mm.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"title": "Hecto",
"name": "hecto",
"pypi_name": "hecto",
"version": "1.0.1",
"version": "1.1.0",
"author": "Juan-Pablo Scaletti",
"author_email": "juanpablo@jpscaletti.com",
"description": "(graph).",
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = hecto
version= 1.0.1
version= 1.1.0
author = Juan-Pablo Scaletti
author_email = juanpablo@jpscaletti.com
description = (graph).
Expand Down

0 comments on commit 3f7ee32

Please sign in to comment.