Skip to content

Commit

Permalink
Handle relative paths and API cleanup + github action
Browse files Browse the repository at this point in the history
  • Loading branch information
lassebje committed Mar 15, 2024
1 parent ccd606c commit 8447c94
Show file tree
Hide file tree
Showing 13 changed files with 155 additions and 121 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Upload Python Package

on:
release:
types: [published]
workflow_dispatch:

permissions:
contents: read

jobs:
deploy:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt -r requirements-dev.txt
- name: Build package
run: python setup.py clean --all sdist bdist_wheel
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
21 changes: 21 additions & 0 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Testing

on: [push]

jobs:
testing:
name: Run tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check out and setup python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install dependencies and linting
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt -r requirements-dev.txt
pylint src --errors-only
- name: Build package
run: pytest --junitxml output/report.xml
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

setup(
name='dmtgen',
version='0.4.2',
version='0.5.0.dev1',
author="SINTEF Ocean",
description="Python generator utilities for DMT",
long_description=long_description,
Expand Down
4 changes: 3 additions & 1 deletion src/dmtgen/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""This module contains the classes for the different types of generators."""
from .package_generator import PackageGenerator
from .base_generator import BaseGenerator
from .basic_template_generator import BasicTemplateGenerator
from .template_generator import TemplateBasedGenerator
from .template_generator import TemplateBasedGenerator
from .none_generator import NoneGenerator
14 changes: 6 additions & 8 deletions src/dmtgen/base_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ def __init__(self, root_dir: Path, package_name: str,
self.output_dir = output_dir
self.source_only = False
self.root_package = root_package
self.generators = self.get_template_generators()

def get_template_generators(self) -> Dict[str,TemplateBasedGenerator]:
""" Override in subclasses """
return {}
# pylint: disable=unused-argument, no-self-use
def get_template_generator(self, template: Path, config: Dict) -> TemplateBasedGenerator:
""" Override in subclasses to control which template generator to use"""
return BasicTemplateGenerator()


def generate_package(self, config: Dict):
""" Generate package """
Expand Down Expand Up @@ -65,12 +66,9 @@ def post_generate(self,output_dir: Path):

def __find_templates_and_generate(self, output_dir: Path, config: Dict):
for path in sorted(output_dir.rglob('*.jinja')):
generator = self.generators.get(path.name,self.get_basic_generator())
generator = self.get_template_generator(path, config)
self.__generate_template(path, generator, config)

def get_basic_generator(self) -> TemplateBasedGenerator:
return BasicTemplateGenerator()

@staticmethod
def __read_template(templatefile: Path):
loader = jinja2.FileSystemLoader(templatefile.parents[0])
Expand Down
31 changes: 3 additions & 28 deletions src/dmtgen/common/blueprint.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
"""Blueprint class for SIMOS"""
from __future__ import annotations
from typing import Dict, Sequence
from typing import TYPE_CHECKING
from .blueprint_attribute import BlueprintAttribute
if TYPE_CHECKING:
from .package import Package
from .blueprint_attribute import BlueprintAttribute



class Blueprint:
""" " A basic SIMOS Blueprint"""
Expand All @@ -26,25 +25,6 @@ def __init__(self, bp_dict: Dict, parent: Package) -> None:
# We will resolve this later
self.__extensions = None

@property
def name(self) -> str:
"""Entity id"""
return self.__name

@name.setter
def name(self, value: str):
"""Set name"""
self.__name = str(value)

@property
def description(self) -> str:
"""Entity id"""
return self.__description

@description.setter
def description(self, value: str):
"""Set description"""
self.__description = str(value)

@property
def abstract(self) -> bool:
Expand All @@ -67,8 +47,6 @@ def all_attributes(self) -> Dict[str,BlueprintAttribute]:
atributes.update(self.__attributes)
return atributes



@property
def extensions(self) -> Sequence[Blueprint]:
"""Extensions"""
Expand All @@ -84,11 +62,8 @@ def __resolve(self,extension: str):

def get_path(self):
""" Get full path to blueprint """
parent = self.get_parent()
parent = self.parent
if parent:
return parent.get_path() + "/" + self.name
# Then we are at root
return "/" + self.name

def get_parent(self) -> Package:
return self.parent
79 changes: 37 additions & 42 deletions src/dmtgen/common/blueprint_attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,67 +10,62 @@ class BlueprintAttribute:

def __init__(self, content: Dict, parent_blueprint: Blueprint) -> None:
self.content = content
if "description" not in content:
content["description"] = ""
name = content["name"]
if not name:
if len(name)==0:
raise ValueError("Attribute has no name")
self.name = name
if "description" not in content:
content["description"] = ""
self.description = content["description"].replace('"',"'")
self.__is_many= "dimensions" in content
self.__contained = content.get("contained",True)
atype = content["attributeType"]
dims=content.get("dimensions")
if dims:
self.dimensions = dims.split(",")
else:
self.dimensions = []

atype = content["attributeType"]
self.parent = parent_blueprint
package = parent_blueprint.parent
self.__type = package.resolve_type(atype)
primitive_types = ['boolean', 'number', 'string', 'integer']
self.__is_primitive = atype in primitive_types
self.type = package.resolve_type(atype)
self.is_primitive = atype in ['boolean', 'number', 'string', 'integer']
self.is_enum = self.content.get("enumType",None) is not None
self.is_blueprint = not (self.is_primitive or self.is_enum)
self.is_optional = self.content.get("optional",True)
self.is_array = len(self.dimensions)>0
self.is_contained = content.get("contained",True)

@property
def name(self) -> str:
"""Entity id"""
return self.__name

@name.setter
def name(self, value: str):
"""Set name"""
self.__name = str(value)
def is_string(self) -> bool:
"""Is this a string"""
return self.type == "string"

@property
def type(self) -> str:
"""Attribute type"""
return self.__type
def is_boolean(self) -> bool:
"""Is this a boolean"""
return self.type == "boolean"

@property
def description(self) -> str:
"""Entity id"""
return self.__description
def is_integer(self) -> bool:
"""Is this an integer"""
return self.type == "integer"

@property
def contained(self) -> bool:
"""Is contained"""
return self.__contained
def is_number(self) -> bool:
"""Is this a number"""
return self.type == "number"

@property
def is_primitive(self) -> bool:
"""Is this a primitive attribute"""
return self.__is_primitive
def is_required(self) -> bool:
"""Is a required relation"""
return not self.is_optional

@property
def is_many(self) -> bool:
"""Is this a many relation"""
return self.__is_many

@property
def optional(self) -> bool:
"""Is this a many relation"""
return self.content.get("optional",True)
def is_fixed_array(self) -> bool:
"""Is this a fixed array"""
return self.is_array and "*" not in self.dimensions

@description.setter
def description(self, value: str):
"""Set description"""
self.__description = str(value)
def is_variable_array(self) -> bool:
"""Is this a variable array"""
return self.is_array and "*" in self.dimensions

def get(self, key, default=None):
"""Return the content value or an optional default"""
Expand Down
28 changes: 4 additions & 24 deletions src/dmtgen/common/enum_description.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
""" A basic DMT Enum"""
from __future__ import annotations
from typing import TYPE_CHECKING, Dict
if TYPE_CHECKING:
from .package import Package



class EnumDescription:
""" " A basic DMT Enum"""

def __init__(self, enum_dict: Dict, parent) -> None:
def __init__(self, enum_dict: Dict, parent: Package) -> None:
self.parent = parent
self.blueprint = enum_dict
self.name = self.blueprint["name"]
Expand All @@ -23,33 +22,14 @@ def __init__(self, enum_dict: Dict, parent) -> None:
"label": labels[i]
})

@property
def name(self) -> str:
"""Entity id"""
return self.__name

@name.setter
def name(self, value: str):
"""Set name"""
self.__name = str(value)

@property
def description(self) -> str:
"""Entity id"""
return self.__description

@description.setter
def description(self, value: str):
"""Set description"""
self.__description = str(value)

def get_path(self):
""" Get full path to blueprint """
parent = self.get_parent()
parent = self.parent
if parent:
return parent.get_path() + "/" + self.name
# Then we are at root
return "/" + self.name

def get_parent(self) -> Package:
""" Get parent package """
return self.parent
Loading

0 comments on commit 8447c94

Please sign in to comment.