Skip to content

Commit

Permalink
Add TemplateConfiguration feature (breaking changes)
Browse files Browse the repository at this point in the history
This commit introduces breaking changes!

TemplateConfiguration class provides the capability to generate the
Template Configuration from various input.
Input can be files or "in-line" configurations (dicts), these are then merged.
The merge functionality has been removed from AS3Declaration entirely,
AS3Declaration now expects a simple dict as template_configuration.

In addition a Template Configuration File or an "in-line" configuration can
use the as3ninja.include namespace to further include configuration files.
Nested includes are not supported (an included file cannot include further files)
and an included file is only processed once (at the first occurance).

Api, Cli and AS3Declaration have been updated accordingly.

Furhter AS3Declaration has a new interface, .declaration and .declaration_asjson
are now .dict() and .json().
AS3Declaration has no .template_configuration and .configuration properties anymore,
AS3TemplateConfiguration is now used for that.

AS3TemplateConfiguration uses a new "parent" Class DictLike.
DictLike makes classes "feel" like a dict.
It adds comparison features, makes dict() class work and provides .get, .keys,
.values, .items methods.
It also modifies __repr__ and __str__.
Any class using DictLike has to set self._dict to the actual target dict, which
DictLike basically proxies.
  • Loading branch information
simonkowallik committed Jan 19, 2020
1 parent 94bc602 commit 53ebf7c
Show file tree
Hide file tree
Showing 21 changed files with 1,154 additions and 324 deletions.
57 changes: 19 additions & 38 deletions as3ninja/api.py
Expand Up @@ -16,6 +16,7 @@
)
from .gitget import Gitget, GitgetException
from .schema import AS3Schema, AS3SchemaVersionError, AS3ValidationError
from .templateconfiguration import AS3TemplateConfiguration, AS3TemplateConfigurationError
from .utils import deserialize

CORS_SETTINGS = {
Expand Down Expand Up @@ -58,13 +59,13 @@ class AS3DeclareGit(BaseModel):
branch: Optional[str]
commit: Optional[str]
depth: int = 1
template_configuration: Optional[Union[str, List[str]]]
template_configuration: Optional[Union[List[Union[dict, str]], dict, str]]


class AS3Declare(BaseModel):
"""Model for an inline AS3 Declaration"""

template_configuration: Union[dict, List[dict]]
template_configuration: Union[List[dict], dict]
declaration_template: str


Expand Down Expand Up @@ -164,17 +165,20 @@ async def post_declaration_transform(as3d: AS3Declare):
"""Transforms an AS3 declaration template, see ``AS3Declare`` for details on the expected input. Returns the AS3 Declaration."""
error = None
try:
d = AS3Declaration(
template_configuration=as3d.template_configuration,
as3tc = AS3TemplateConfiguration(as3d.template_configuration)

as3declaration = AS3Declaration(
template_configuration=as3tc.dict(),
declaration_template=as3d.declaration_template,
)
return d.declaration
return as3declaration.dict()

except (
AS3SchemaVersionError,
AS3JSONDecodeError,
AS3TemplateSyntaxError,
AS3UndefinedError,
AS3TemplateConfigurationError,
) as exc:
error = Error(code=400, message=str(exc))
raise HTTPException(status_code=error.code, detail=error.message)
Expand All @@ -185,53 +189,30 @@ async def post_declaration_git_transform(as3d: AS3DeclareGit):
"""Transforms an AS3 declaration template, see ``AS3DeclareGit`` for details on the expected input. Returns the AS3 Declaration."""
error = None
try:
template_configuration: list = []
with Gitget(
repository=as3d.repository,
branch=as3d.branch,
commit=as3d.commit,
depth=as3d.depth,
) as gitrepo:
if as3d.template_configuration and isinstance(
as3d.template_configuration, list
):
for config_file in as3d.template_configuration:
template_configuration.append(
deserialize(datasource=f"{gitrepo.repodir}/{config_file}")
)
elif as3d.template_configuration:
template_configuration.append(
deserialize(
datasource=f"{gitrepo.repodir}/{as3d.template_configuration}"
)
)
else:
try:
template_configuration.append(
deserialize(datasource=f"{gitrepo.repodir}/ninja.json")
)
except:
# json failed, try yaml, then yml
try:
template_configuration.append(
deserialize(datasource=f"{gitrepo.repodir}/ninja.yaml")
)
except:
template_configuration.append(
deserialize(datasource=f"{gitrepo.repodir}/ninja.yml")
)
template_configuration.append({"as3ninja": {"git": gitrepo.info}})
d = AS3Declaration(
template_configuration=template_configuration,
as3tc = AS3TemplateConfiguration(
template_configuration=as3d.template_configuration,
base_path=f"{gitrepo.repodir}/",
overlay={"as3ninja": {"git": gitrepo.info}},
)

as3declaration = AS3Declaration(
template_configuration=as3tc.dict(),
jinja2_searchpath=gitrepo.repodir,
)
return d.declaration
return as3declaration.dict()
except (
GitgetException,
AS3SchemaVersionError,
AS3JSONDecodeError,
AS3TemplateSyntaxError,
AS3UndefinedError,
AS3TemplateConfigurationError,
) as exc:
error = Error(code=400, message=str(exc))
raise HTTPException(status_code=error.code, detail=error.message)
Expand Down
72 changes: 30 additions & 42 deletions as3ninja/cli.py
Expand Up @@ -12,6 +12,7 @@
from .declaration import AS3Declaration
from .gitget import Gitget
from .schema import AS3Schema
from .templateconfiguration import AS3TemplateConfiguration, AS3TemplateConfigurationError
from .utils import deserialize

# TODO: figure out how click can raise an non-zero exit code on AS3ValidationError
Expand Down Expand Up @@ -66,40 +67,27 @@ def transform(
pretty: bool,
):
"""Transforms a declaration template using the configuration file to an AS3 delcaration which is validated against the JSON schema."""
template_configuration: list = []
if configuration_file:
for config_file in configuration_file:
template_configuration.append(deserialize(datasource=config_file))
else:
try:
template_configuration.append(deserialize(datasource="./ninja.json"))
except:
# json failed, try yaml, then yml
try:
template_configuration.append(deserialize(datasource="./ninja.yaml"))
except:
template_configuration.append(deserialize(datasource="./ninja.yml"))

if declaration_template:
template = declaration_template.read()
else:
template = None

as3d = AS3Declaration(
declaration_template=template, template_configuration=template_configuration
as3tc = AS3TemplateConfiguration(template_configuration=configuration_file)
as3declaration = AS3Declaration(
declaration_template=template, template_configuration=as3tc.dict()
)

if validate:
as3s = AS3Schema()
as3s.validate(declaration=as3d.declaration)
as3s.validate(declaration=as3declaration.dict())

if output_file:
output_file.write(as3d.declaration_asjson)
output_file.write(as3declaration.json())
else:
if pretty:
print(json.dumps(as3d.declaration, indent=4, sort_keys=True))
print(json.dumps(as3declaration.dict(), indent=4, sort_keys=True))
else:
print(as3d.declaration_asjson)
print(as3declaration.json())


@cli.command()
Expand All @@ -120,12 +108,22 @@ def transform(
@click.option(
"--pretty", required=False, default=False, is_flag=True, help="Pretty print JSON"
)
@click.option(
"-c",
"--configuration-file",
required=False,
nargs=0,
type=str,
help="JSON/YAML configuration file used to parameterize declaration template",
)
@click.argument("configuration-file", nargs=-1)
@click.option("--repository", required=True, default=False, help="Git repository")
@click.option("--branch", required=False, default=False, help="Git branch to use")
@click.option("--commit", required=False, default=False, help="Git commit id (long)")
@click.option("--depth", required=False, default=False, help="Git clone depth")
@logger.catch
def git_transform(
configuration_file: Optional[tuple],
repository: str,
branch: Union[str, None],
commit: Union[str, None],
Expand All @@ -137,37 +135,27 @@ def git_transform(
"""Transforms a declaration from a git repository using either the default configuration files (ninja.json/yaml/yml) or the configuration file specified through the command line.
The AS3 delcaration which is validated against the JSON schema.
"""
template_configuration: list = []
with Gitget(
repository=repository, branch=branch, commit=commit, depth=depth
) as gitrepo:
try:
template_configuration.append(
deserialize(datasource=f"{gitrepo.repodir}/ninja.json")
)
except:
# json failed, try yaml, then yml
try:
template_configuration.append(
deserialize(datasource=f"{gitrepo.repodir}/ninja.yaml")
)
except:
template_configuration.append(
deserialize(datasource=f"{gitrepo.repodir}/ninja.yml")
)
template_configuration.append({"as3ninja": {"git": gitrepo.info}})
as3d = AS3Declaration(
template_configuration=template_configuration,
as3tc = AS3TemplateConfiguration(
template_configuration=configuration_file,
base_path=f"{gitrepo.repodir}/",
overlay={"as3ninja": {"git": gitrepo.info}},
)

as3declaration = AS3Declaration(
template_configuration=as3tc.dict(),
jinja2_searchpath=gitrepo.repodir,
)
if validate:
as3s = AS3Schema()
as3s.validate(declaration=as3d.declaration)
as3s.validate(declaration=as3declaration.dict())

if output_file:
output_file.write(as3d.declaration_asjson)
output_file.write(as3declaration.json())
else:
if pretty:
print(json.dumps(as3d.declaration, indent=4, sort_keys=True))
print(json.dumps(as3declaration.dict(), indent=4, sort_keys=True))
else:
print(as3d.declaration_asjson)
print(as3declaration.json())

0 comments on commit 53ebf7c

Please sign in to comment.