-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
updates to the release GA #513
Changes from 7 commits
9dc45bf
5fb26fa
d604256
f88980f
fddd258
d6816d6
e1ac0d1
2bf12d6
5970241
d14fb10
ccba7f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,33 @@ jobs: | |
python scripts/jsonParser.py | ||
reproschema validate examples | ||
|
||
generate_other_formats: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Set up Python | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: 3.12 | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip setuptools | ||
pip install linkml astor pre-commit | ||
pip install git+https://github.com/ReproNim/reproschema-py.git | ||
- name: generate pydantic and fixing it | ||
run: | | ||
gen-pydantic --pydantic-version 2 linkml-schema/reproschema.yaml > reproschema_model_autogen.py | ||
python scripts/fix_pydantic.py reproschema_model_autogen.py reproschema_model.py | ||
pre-commit run --files reproschema_model.py | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if the file is auto-generated we could just not lint it with pre-commit, but if we do then this step in workflow must have continue-on-error or an always otherwise precommit will fail and stop everything: see here https://github.com/ReproNim/reproschema/actions/runs/9568185070/job/26377757321?pr=513#step:5:162 I think always() is the recommended way or that continue-on-error was deprecated There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should run this at some point, since this will be later added to reproschema-py (and perhaps if we do it here it will be easier to automatically push to to reproschema-py) |
||
- name: generate jsonld | ||
run: | | ||
gen-jsonld --context contexts/reproschema linkml-schema/reproschema.yaml > reproschema.jsonld | ||
- name: generate n-triples and turtle formats using reproschema | ||
run: | | ||
reproschema convert --format n-triples reproschema.jsonld > reproschema.nt | ||
reproschema convert --format turtle reproschema.jsonld > reproschema.ttl | ||
|
||
|
||
release: | ||
needs: [validate] | ||
if: github.event_name == 'workflow_dispatch' | ||
|
@@ -51,7 +78,11 @@ jobs: | |
run: | | ||
echo "Making a release ${{ inputs.version }}" | ||
mkdir releases/${{ inputs.version }} | ||
cp contexts/reproschema releases/${{ inputs.version }}/base | ||
cp contexts/reproschema releases/${{ inputs.version }}/reproschema | ||
cp reproschema_model.py releases/${{ inputs.version }}/reproschema_model.py | ||
cp reproschema.jsonld releases/${{ inputs.version }}/reproschema.jsonld | ||
cp reproschema.nt releases/${{ inputs.version }}/reproschema.nt | ||
cp reproschema.ttl releases/${{ inputs.version }}/reproschema.ttl | ||
# python scripts/makeRelease.py ${{ inputs.version }} | ||
|
||
- name: Open pull requests to add files | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
""" Using ast transformer to fix some issues with automatic pydantic generation""" | ||
|
||
import sys | ||
import ast | ||
import astor | ||
|
||
|
||
class ClassRemover(ast.NodeTransformer): | ||
def __init__(self, class_name): | ||
self.class_name = class_name | ||
|
||
def visit_ClassDef(self, node): | ||
# Remove the class if its name matches the class_to_remove | ||
if node.name == self.class_name: | ||
return None | ||
return node | ||
|
||
def visit_Expr(self, node): | ||
# Check if the node is a call expression | ||
if isinstance(node.value, ast.Call): | ||
# Check if the call expression is an attribute (method call) | ||
if isinstance(node.value.func, ast.Attribute): | ||
# Check if the method call matches the specified class and method name | ||
if ( | ||
isinstance(node.value.func.value, ast.Name) | ||
and node.value.func.value.id == self.class_name | ||
): | ||
return None # Remove this node | ||
return self.generic_visit(node) | ||
|
||
|
||
class TypeReplacer(ast.NodeTransformer): | ||
def __init__(self, old_type, new_type): | ||
self.old_type = old_type | ||
self.new_type = new_type | ||
|
||
def visit_FunctionDef(self, node): | ||
# Check all arguments in the function definition | ||
for arg in node.args.args: | ||
if arg.annotation: | ||
arg.annotation = self.visit(arg.annotation) | ||
return self.generic_visit(node) | ||
|
||
def visit_AsyncFunctionDef(self, node): | ||
# Handle async function definitions similarly | ||
for arg in node.args.args: | ||
if arg.annotation: | ||
arg.annotation = self.visit(arg.annotation) | ||
return self.generic_visit(node) | ||
|
||
def visit_Name(self, node): | ||
# Replace the old type with the new type | ||
if node.id == self.old_type: | ||
node.id = self.new_type | ||
return node | ||
|
||
def visit_Subscript(self, node): | ||
# Handle Union, Optional, and other subscripted types | ||
node.value = self.visit(node.value) | ||
node.slice = self.visit(node.slice) | ||
return node | ||
|
||
def visit_Index(self, node): | ||
# Handle the index part of subscripted types | ||
node.value = self.visit(node.value) | ||
return node | ||
|
||
def visit_Tuple(self, node): | ||
# Handle tuples in type annotations | ||
node.elts = [self.visit(elt) for elt in node.elts] | ||
return node | ||
|
||
|
||
def edit_pydantic(input_file, output_file): | ||
|
||
with open(input_file, "r") as file: | ||
tree = ast.parse(file.read()) | ||
|
||
transformer_class = ClassRemover(class_name="LangString") | ||
tree_modclass = transformer_class.visit(tree) | ||
|
||
transformer_tp = TypeReplacer(old_type="LangString", new_type="Dict[str, str]") | ||
tree_modclass_modtype = transformer_tp.visit(tree_modclass) | ||
|
||
with open(output_file, "w") as file: | ||
file.write(astor.to_source(tree_modclass_modtype)) | ||
|
||
|
||
if __name__ == "__main__": | ||
input_file = sys.argv[1] | ||
if len(sys.argv) < 3: | ||
output_file = input_file | ||
else: | ||
output_file = sys.argv[2] | ||
print( | ||
f"Fixing automatically generated pydantic file {input_file} and saving to {output_file}" | ||
) | ||
edit_pydantic(input_file, output_file) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note that this will generate the files on every PR but that they will no be added to the repo or the release
files generated on a given job are not passed the following ones in github action, so maybe better to have the file generation happen in the release job
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I didn't get the structure at the beginning, just moved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will be testing
|| true